<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>01 - 对称加密 | AJ</title>
    <meta name="generator" content="VuePress 1.5.0">
    <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
    <script>
            var _hmt = _hmt || [];
            (function() {
            var hm = document.createElement("script");
            hm.src = "https://hm.baidu.com/hm.js?51b8c2e72d1adf96524638ce85bb7d72";
            var s = document.getElementsByTagName("script")[0]; 
            s.parentNode.insertBefore(hm, s);

            // 引入谷歌,不需要可删除这段
            var hm1 = document.createElement("script");
            hm1.src = "https://www.googletagmanager.com/gtag/js?id=G-B7351EYS04";
            var s1 = document.getElementsByTagName("script")[0]; 
            s1.parentNode.insertBefore(hm1, s1);
            })();

            // 谷歌加载,不需要可删除
            window.dataLayer = window.dataLayer || [];
            function gtag(){dataLayer.push(arguments);}
            gtag('js', new Date());

            gtag('config', 'G-B7351EYS04');
        </script>
    <meta name="description" content="阿俊博客|记录一个程序员的成长历程 阿俊博客(blog.zhequtao.com)记录一个后端程序员的成长历程,分享他的学习笔记和心得,还有些开发必备技巧哦! java golang web html dev开发">
    <link rel="preload" href="/assets/css/0.styles.a3df589e.css" as="style"><link rel="preload" href="/assets/js/app.cb35c8f6.js" as="script"><link rel="preload" href="/assets/js/2.063846a6.js" as="script"><link rel="preload" href="/assets/js/4.1ffb4609.js" as="script"><link rel="preload" href="/assets/js/46.90855a0f.js" as="script"><link rel="prefetch" href="/assets/js/10.5629fe4d.js"><link rel="prefetch" href="/assets/js/100.8417ccea.js"><link rel="prefetch" href="/assets/js/101.37fdb377.js"><link rel="prefetch" href="/assets/js/102.848b686d.js"><link rel="prefetch" href="/assets/js/103.6a2489a0.js"><link rel="prefetch" href="/assets/js/104.99e8899f.js"><link rel="prefetch" href="/assets/js/105.8b741763.js"><link rel="prefetch" href="/assets/js/106.08163715.js"><link rel="prefetch" href="/assets/js/107.21801349.js"><link rel="prefetch" href="/assets/js/108.e3a2892b.js"><link rel="prefetch" href="/assets/js/109.dab5618c.js"><link rel="prefetch" href="/assets/js/11.cddc1623.js"><link rel="prefetch" href="/assets/js/110.f5249b39.js"><link rel="prefetch" href="/assets/js/111.9abf8bce.js"><link rel="prefetch" href="/assets/js/112.8eb86924.js"><link rel="prefetch" href="/assets/js/113.c180ed46.js"><link rel="prefetch" href="/assets/js/114.2370f5b5.js"><link rel="prefetch" href="/assets/js/115.88dc3fd8.js"><link rel="prefetch" href="/assets/js/116.63403600.js"><link rel="prefetch" href="/assets/js/117.83674aa0.js"><link rel="prefetch" href="/assets/js/118.9c58c685.js"><link rel="prefetch" href="/assets/js/119.621f9a70.js"><link rel="prefetch" href="/assets/js/12.ff3d03f5.js"><link rel="prefetch" href="/assets/js/120.a6d2b7f7.js"><link rel="prefetch" href="/assets/js/121.ae0ce9d1.js"><link rel="prefetch" href="/assets/js/122.de240e6d.js"><link rel="prefetch" href="/assets/js/123.b043e3e4.js"><link rel="prefetch" href="/assets/js/124.550af937.js"><link rel="prefetch" href="/assets/js/125.6f06b34c.js"><link rel="prefetch" href="/assets/js/126.38d64604.js"><link rel="prefetch" href="/assets/js/127.a948db56.js"><link rel="prefetch" href="/assets/js/128.4ca789e0.js"><link rel="prefetch" href="/assets/js/129.59be4505.js"><link rel="prefetch" href="/assets/js/13.e9f75cc3.js"><link rel="prefetch" href="/assets/js/130.ddae76a9.js"><link rel="prefetch" href="/assets/js/131.d969c265.js"><link rel="prefetch" href="/assets/js/132.5f43ce5c.js"><link rel="prefetch" href="/assets/js/133.b651af22.js"><link rel="prefetch" href="/assets/js/134.2499236a.js"><link rel="prefetch" href="/assets/js/135.4180596c.js"><link rel="prefetch" href="/assets/js/136.2c309233.js"><link rel="prefetch" href="/assets/js/137.72ca42dd.js"><link rel="prefetch" href="/assets/js/138.3772cd38.js"><link rel="prefetch" href="/assets/js/139.1d0a53da.js"><link rel="prefetch" href="/assets/js/14.be4b89ed.js"><link rel="prefetch" href="/assets/js/140.22368353.js"><link rel="prefetch" href="/assets/js/141.a14aef3c.js"><link rel="prefetch" href="/assets/js/142.2041ce3a.js"><link rel="prefetch" href="/assets/js/143.377262ec.js"><link rel="prefetch" href="/assets/js/144.8fcbc368.js"><link rel="prefetch" href="/assets/js/145.46da36bf.js"><link rel="prefetch" href="/assets/js/146.eceae0d9.js"><link rel="prefetch" href="/assets/js/147.e1bd6531.js"><link rel="prefetch" href="/assets/js/148.76f193ce.js"><link rel="prefetch" href="/assets/js/149.587bd581.js"><link rel="prefetch" href="/assets/js/15.e3219ac0.js"><link rel="prefetch" href="/assets/js/150.169c71e0.js"><link rel="prefetch" href="/assets/js/151.384021ea.js"><link rel="prefetch" href="/assets/js/152.0f20cf03.js"><link rel="prefetch" href="/assets/js/153.fd94af1e.js"><link rel="prefetch" href="/assets/js/154.a550f5dc.js"><link rel="prefetch" href="/assets/js/155.ba1ae86e.js"><link rel="prefetch" href="/assets/js/156.3b98ded0.js"><link rel="prefetch" href="/assets/js/157.cd378596.js"><link rel="prefetch" href="/assets/js/158.c138d0df.js"><link rel="prefetch" href="/assets/js/159.2635f7f4.js"><link rel="prefetch" href="/assets/js/16.c9c35d42.js"><link rel="prefetch" href="/assets/js/160.d51b4126.js"><link rel="prefetch" href="/assets/js/161.5dc29e7b.js"><link rel="prefetch" href="/assets/js/162.f257a92b.js"><link rel="prefetch" href="/assets/js/163.9eb75e40.js"><link rel="prefetch" href="/assets/js/164.8fb1e22b.js"><link rel="prefetch" href="/assets/js/165.49255503.js"><link rel="prefetch" href="/assets/js/166.e54539e6.js"><link rel="prefetch" href="/assets/js/167.a06acdb0.js"><link rel="prefetch" href="/assets/js/168.948ab620.js"><link rel="prefetch" href="/assets/js/169.7d756812.js"><link rel="prefetch" href="/assets/js/17.81067bc8.js"><link rel="prefetch" href="/assets/js/170.ffe63330.js"><link rel="prefetch" href="/assets/js/171.835398b9.js"><link rel="prefetch" href="/assets/js/172.3987be39.js"><link rel="prefetch" href="/assets/js/173.e3cedb8a.js"><link rel="prefetch" href="/assets/js/174.11a32588.js"><link rel="prefetch" href="/assets/js/175.da6f9782.js"><link rel="prefetch" href="/assets/js/176.50e55edc.js"><link rel="prefetch" href="/assets/js/177.a89a1d17.js"><link rel="prefetch" href="/assets/js/178.7ad3ce84.js"><link rel="prefetch" href="/assets/js/179.98a1343b.js"><link rel="prefetch" href="/assets/js/18.b67caf4c.js"><link rel="prefetch" href="/assets/js/180.4e98599b.js"><link rel="prefetch" href="/assets/js/181.dd885afd.js"><link rel="prefetch" href="/assets/js/182.789990c8.js"><link rel="prefetch" href="/assets/js/183.f11ca2fd.js"><link rel="prefetch" href="/assets/js/184.fcf128ec.js"><link rel="prefetch" href="/assets/js/185.54e1e9b6.js"><link rel="prefetch" href="/assets/js/186.db91021a.js"><link rel="prefetch" href="/assets/js/187.5309dd42.js"><link rel="prefetch" href="/assets/js/188.615821ea.js"><link rel="prefetch" href="/assets/js/189.f23f1d42.js"><link rel="prefetch" href="/assets/js/19.294a011c.js"><link rel="prefetch" href="/assets/js/190.efe894bc.js"><link rel="prefetch" href="/assets/js/191.0d14904a.js"><link rel="prefetch" href="/assets/js/192.efd25a9e.js"><link rel="prefetch" href="/assets/js/193.88151f34.js"><link rel="prefetch" href="/assets/js/194.efedce14.js"><link rel="prefetch" href="/assets/js/195.03ac15bb.js"><link rel="prefetch" href="/assets/js/196.fbc18389.js"><link rel="prefetch" href="/assets/js/197.0257ab5e.js"><link rel="prefetch" href="/assets/js/198.f1de2817.js"><link rel="prefetch" href="/assets/js/199.8f1c166b.js"><link rel="prefetch" href="/assets/js/20.1a41edb1.js"><link rel="prefetch" href="/assets/js/200.4af99727.js"><link rel="prefetch" href="/assets/js/201.9f8caef1.js"><link rel="prefetch" href="/assets/js/202.6f07d705.js"><link rel="prefetch" href="/assets/js/203.5012fe50.js"><link rel="prefetch" href="/assets/js/204.3a0dfd8e.js"><link rel="prefetch" href="/assets/js/205.0ba9b606.js"><link rel="prefetch" href="/assets/js/206.663a49ec.js"><link rel="prefetch" href="/assets/js/207.b2406149.js"><link rel="prefetch" href="/assets/js/208.b0b2dfd8.js"><link rel="prefetch" href="/assets/js/209.41a0ec9f.js"><link rel="prefetch" href="/assets/js/21.b6ea6f9a.js"><link rel="prefetch" href="/assets/js/210.6f36beb8.js"><link rel="prefetch" href="/assets/js/211.90ef6e5c.js"><link rel="prefetch" href="/assets/js/212.42339063.js"><link rel="prefetch" href="/assets/js/213.a2bfeda9.js"><link rel="prefetch" href="/assets/js/214.5c7eb42a.js"><link rel="prefetch" href="/assets/js/215.18260ae5.js"><link rel="prefetch" href="/assets/js/216.7678fd29.js"><link rel="prefetch" href="/assets/js/217.9d936f88.js"><link rel="prefetch" href="/assets/js/218.bac403c4.js"><link rel="prefetch" href="/assets/js/219.9d8cb16b.js"><link rel="prefetch" href="/assets/js/22.367cc253.js"><link rel="prefetch" href="/assets/js/220.375b7707.js"><link rel="prefetch" href="/assets/js/221.3e400da4.js"><link rel="prefetch" href="/assets/js/222.8fbd2857.js"><link rel="prefetch" href="/assets/js/223.76a10075.js"><link rel="prefetch" href="/assets/js/224.ff94cc4e.js"><link rel="prefetch" href="/assets/js/225.d4688ca6.js"><link rel="prefetch" href="/assets/js/226.b13b18af.js"><link rel="prefetch" href="/assets/js/227.288d0f96.js"><link rel="prefetch" href="/assets/js/228.60430ac0.js"><link rel="prefetch" href="/assets/js/229.da728342.js"><link rel="prefetch" href="/assets/js/23.bc3de730.js"><link rel="prefetch" href="/assets/js/230.d8417d20.js"><link rel="prefetch" href="/assets/js/231.6a9ce0b4.js"><link rel="prefetch" href="/assets/js/232.7611b413.js"><link rel="prefetch" href="/assets/js/233.94712cf9.js"><link rel="prefetch" href="/assets/js/234.93888298.js"><link rel="prefetch" href="/assets/js/235.62506981.js"><link rel="prefetch" href="/assets/js/236.5a055c7c.js"><link rel="prefetch" href="/assets/js/237.0a6c4902.js"><link rel="prefetch" href="/assets/js/238.e5f37663.js"><link rel="prefetch" href="/assets/js/239.331bba86.js"><link rel="prefetch" href="/assets/js/24.82f0901c.js"><link rel="prefetch" href="/assets/js/240.59591cfc.js"><link rel="prefetch" href="/assets/js/241.ce671f47.js"><link rel="prefetch" href="/assets/js/242.fb2542fa.js"><link rel="prefetch" href="/assets/js/243.74abc73d.js"><link rel="prefetch" href="/assets/js/244.ecd707b2.js"><link rel="prefetch" href="/assets/js/245.d728367b.js"><link rel="prefetch" href="/assets/js/246.9270e7fe.js"><link rel="prefetch" href="/assets/js/247.a421ba15.js"><link rel="prefetch" href="/assets/js/248.e759132e.js"><link rel="prefetch" href="/assets/js/249.3077fb46.js"><link rel="prefetch" href="/assets/js/25.95c551dc.js"><link rel="prefetch" href="/assets/js/250.5fe4dd03.js"><link rel="prefetch" href="/assets/js/251.4b8fe76c.js"><link rel="prefetch" href="/assets/js/252.0d1cf7ea.js"><link rel="prefetch" href="/assets/js/253.89d16ba0.js"><link rel="prefetch" href="/assets/js/254.8d1afc68.js"><link rel="prefetch" href="/assets/js/255.64e680cb.js"><link rel="prefetch" href="/assets/js/256.9defbd0e.js"><link rel="prefetch" href="/assets/js/257.1fef24fd.js"><link rel="prefetch" href="/assets/js/258.4e205286.js"><link rel="prefetch" href="/assets/js/259.f3d56efc.js"><link rel="prefetch" href="/assets/js/26.7fe56bac.js"><link rel="prefetch" href="/assets/js/260.378299e6.js"><link rel="prefetch" href="/assets/js/261.8e4fb397.js"><link rel="prefetch" href="/assets/js/262.54595d98.js"><link rel="prefetch" href="/assets/js/263.fb333dc1.js"><link rel="prefetch" href="/assets/js/264.13d13301.js"><link rel="prefetch" href="/assets/js/265.c85104bc.js"><link rel="prefetch" href="/assets/js/266.9f3d1f1c.js"><link rel="prefetch" href="/assets/js/267.fb392815.js"><link rel="prefetch" href="/assets/js/268.add7eacb.js"><link rel="prefetch" href="/assets/js/269.7e49fcc7.js"><link rel="prefetch" href="/assets/js/27.5547e5f0.js"><link rel="prefetch" href="/assets/js/270.22342070.js"><link rel="prefetch" href="/assets/js/271.59917b1a.js"><link rel="prefetch" href="/assets/js/272.4a4751d5.js"><link rel="prefetch" href="/assets/js/273.f4c2fa5c.js"><link rel="prefetch" href="/assets/js/274.1208bc94.js"><link rel="prefetch" href="/assets/js/275.f6528753.js"><link rel="prefetch" href="/assets/js/276.a68772cd.js"><link rel="prefetch" href="/assets/js/277.f154ab32.js"><link rel="prefetch" href="/assets/js/278.bb616a63.js"><link rel="prefetch" href="/assets/js/279.6a356cff.js"><link rel="prefetch" href="/assets/js/28.b08b2847.js"><link rel="prefetch" href="/assets/js/280.5afc20fc.js"><link rel="prefetch" href="/assets/js/281.3cd86225.js"><link rel="prefetch" href="/assets/js/282.3ecb92aa.js"><link rel="prefetch" href="/assets/js/283.85159ea7.js"><link rel="prefetch" href="/assets/js/284.b6545c68.js"><link rel="prefetch" href="/assets/js/285.5e83ee29.js"><link rel="prefetch" href="/assets/js/286.2aad298d.js"><link rel="prefetch" href="/assets/js/287.3ca76244.js"><link rel="prefetch" href="/assets/js/288.5b17963d.js"><link rel="prefetch" href="/assets/js/289.f47a759b.js"><link rel="prefetch" href="/assets/js/29.562dbf7d.js"><link rel="prefetch" href="/assets/js/290.36b603c7.js"><link rel="prefetch" href="/assets/js/291.a9bd8951.js"><link rel="prefetch" href="/assets/js/292.dfc54f28.js"><link rel="prefetch" href="/assets/js/293.2d061212.js"><link rel="prefetch" href="/assets/js/294.6d564a9e.js"><link rel="prefetch" href="/assets/js/295.a31dd593.js"><link rel="prefetch" href="/assets/js/296.3101e5e8.js"><link rel="prefetch" href="/assets/js/297.7efde936.js"><link rel="prefetch" href="/assets/js/298.8bb3aa68.js"><link rel="prefetch" href="/assets/js/299.8b51e6bd.js"><link rel="prefetch" href="/assets/js/3.76257eb7.js"><link rel="prefetch" href="/assets/js/30.221adea2.js"><link rel="prefetch" href="/assets/js/300.62effe45.js"><link rel="prefetch" href="/assets/js/301.98c863c5.js"><link rel="prefetch" href="/assets/js/302.e3493ab2.js"><link rel="prefetch" href="/assets/js/303.800c8028.js"><link rel="prefetch" href="/assets/js/304.b6f08986.js"><link rel="prefetch" href="/assets/js/305.09af356b.js"><link rel="prefetch" href="/assets/js/306.d0d3589d.js"><link rel="prefetch" href="/assets/js/307.ee2fd249.js"><link rel="prefetch" href="/assets/js/308.f3f76368.js"><link rel="prefetch" href="/assets/js/309.d2b5ce40.js"><link rel="prefetch" href="/assets/js/31.334fc8bb.js"><link rel="prefetch" href="/assets/js/310.b4fa2feb.js"><link rel="prefetch" href="/assets/js/311.7d747ef3.js"><link rel="prefetch" href="/assets/js/312.89bdff40.js"><link rel="prefetch" href="/assets/js/313.875b82fe.js"><link rel="prefetch" href="/assets/js/314.0bbe51c4.js"><link rel="prefetch" href="/assets/js/315.cc07dbcf.js"><link rel="prefetch" href="/assets/js/316.bc72b152.js"><link rel="prefetch" href="/assets/js/317.55462812.js"><link rel="prefetch" href="/assets/js/318.a158fda0.js"><link rel="prefetch" href="/assets/js/319.b03a5bd2.js"><link rel="prefetch" href="/assets/js/32.d6826b16.js"><link rel="prefetch" href="/assets/js/320.a5bd19b0.js"><link rel="prefetch" href="/assets/js/321.4f9faaa7.js"><link rel="prefetch" href="/assets/js/322.dbd3b4fa.js"><link rel="prefetch" href="/assets/js/323.a04e2062.js"><link rel="prefetch" href="/assets/js/324.c45b46cf.js"><link rel="prefetch" href="/assets/js/325.cd1460c4.js"><link rel="prefetch" href="/assets/js/326.bd90ef85.js"><link rel="prefetch" href="/assets/js/327.8bf38ef7.js"><link rel="prefetch" href="/assets/js/328.99e9aed3.js"><link rel="prefetch" href="/assets/js/329.de0012cb.js"><link rel="prefetch" href="/assets/js/33.b1059062.js"><link rel="prefetch" href="/assets/js/330.59f11391.js"><link rel="prefetch" href="/assets/js/331.6d16a13c.js"><link rel="prefetch" href="/assets/js/332.922ca235.js"><link rel="prefetch" href="/assets/js/333.c94c3602.js"><link rel="prefetch" href="/assets/js/334.77e02010.js"><link rel="prefetch" href="/assets/js/335.1e0c4f7b.js"><link rel="prefetch" href="/assets/js/336.5675dc4f.js"><link rel="prefetch" href="/assets/js/337.bb6e11dc.js"><link rel="prefetch" href="/assets/js/338.294981e9.js"><link rel="prefetch" href="/assets/js/339.d0376372.js"><link rel="prefetch" href="/assets/js/34.0c7d5782.js"><link rel="prefetch" href="/assets/js/340.64596428.js"><link rel="prefetch" href="/assets/js/341.ec0f9409.js"><link rel="prefetch" href="/assets/js/342.7abc47c4.js"><link rel="prefetch" href="/assets/js/343.4262d486.js"><link rel="prefetch" href="/assets/js/344.8729ad8c.js"><link rel="prefetch" href="/assets/js/345.c210d888.js"><link rel="prefetch" href="/assets/js/346.6f42f7cb.js"><link rel="prefetch" href="/assets/js/347.81b41ae5.js"><link rel="prefetch" href="/assets/js/348.07eca37c.js"><link rel="prefetch" href="/assets/js/349.8019d6f3.js"><link rel="prefetch" href="/assets/js/35.ae14e37f.js"><link rel="prefetch" href="/assets/js/350.57da2e7b.js"><link rel="prefetch" href="/assets/js/351.2e99afdf.js"><link rel="prefetch" href="/assets/js/352.67dd88b7.js"><link rel="prefetch" href="/assets/js/353.15b9f624.js"><link rel="prefetch" href="/assets/js/354.a63e8432.js"><link rel="prefetch" href="/assets/js/355.bbc16ee9.js"><link rel="prefetch" href="/assets/js/356.ff63d3bb.js"><link rel="prefetch" href="/assets/js/357.4fb2d941.js"><link rel="prefetch" href="/assets/js/358.55182977.js"><link rel="prefetch" href="/assets/js/359.265c3d26.js"><link rel="prefetch" href="/assets/js/36.b9ed4cf1.js"><link rel="prefetch" href="/assets/js/360.ced80eb3.js"><link rel="prefetch" href="/assets/js/361.afe6ba84.js"><link rel="prefetch" href="/assets/js/362.c2b62518.js"><link rel="prefetch" href="/assets/js/363.0c4a4800.js"><link rel="prefetch" href="/assets/js/364.ce60291b.js"><link rel="prefetch" href="/assets/js/365.0e3a61f9.js"><link rel="prefetch" href="/assets/js/366.d53ccb03.js"><link rel="prefetch" href="/assets/js/367.689e464d.js"><link rel="prefetch" href="/assets/js/368.418c571f.js"><link rel="prefetch" href="/assets/js/369.c2fff3c8.js"><link rel="prefetch" href="/assets/js/37.a021ac57.js"><link rel="prefetch" href="/assets/js/370.a932b958.js"><link rel="prefetch" href="/assets/js/371.7d153241.js"><link rel="prefetch" href="/assets/js/372.fb9878fa.js"><link rel="prefetch" href="/assets/js/373.85772e03.js"><link rel="prefetch" href="/assets/js/374.b4a8b1b6.js"><link rel="prefetch" href="/assets/js/375.32f70596.js"><link rel="prefetch" href="/assets/js/376.a16d79a8.js"><link rel="prefetch" href="/assets/js/377.c996b7e1.js"><link rel="prefetch" href="/assets/js/378.d37d15c7.js"><link rel="prefetch" href="/assets/js/379.b81ba7dd.js"><link rel="prefetch" href="/assets/js/38.89138658.js"><link rel="prefetch" href="/assets/js/380.524c9b31.js"><link rel="prefetch" href="/assets/js/381.7ebfd6db.js"><link rel="prefetch" href="/assets/js/382.29edda0f.js"><link rel="prefetch" href="/assets/js/383.9642a212.js"><link rel="prefetch" href="/assets/js/384.086e3b42.js"><link rel="prefetch" href="/assets/js/385.a9bb46a8.js"><link rel="prefetch" href="/assets/js/386.f2561a39.js"><link rel="prefetch" href="/assets/js/387.ba9b6aaa.js"><link rel="prefetch" href="/assets/js/388.e0ace495.js"><link rel="prefetch" href="/assets/js/389.ba8c09dd.js"><link rel="prefetch" href="/assets/js/39.04f331e3.js"><link rel="prefetch" href="/assets/js/390.de1bb48b.js"><link rel="prefetch" href="/assets/js/391.7cc6edeb.js"><link rel="prefetch" href="/assets/js/392.0493a6f7.js"><link rel="prefetch" href="/assets/js/393.ba2d3e62.js"><link rel="prefetch" href="/assets/js/394.b3aa9224.js"><link rel="prefetch" href="/assets/js/395.f4df3a60.js"><link rel="prefetch" href="/assets/js/396.09644790.js"><link rel="prefetch" href="/assets/js/397.76163964.js"><link rel="prefetch" href="/assets/js/398.377fd8fc.js"><link rel="prefetch" href="/assets/js/399.39059be5.js"><link rel="prefetch" href="/assets/js/40.a21abf05.js"><link rel="prefetch" href="/assets/js/400.559a547f.js"><link rel="prefetch" href="/assets/js/401.bc6d738c.js"><link rel="prefetch" href="/assets/js/402.c504ed7b.js"><link rel="prefetch" href="/assets/js/403.77a0af9c.js"><link rel="prefetch" href="/assets/js/404.0f408cc6.js"><link rel="prefetch" href="/assets/js/405.90b0bab6.js"><link rel="prefetch" href="/assets/js/406.01b11432.js"><link rel="prefetch" href="/assets/js/407.58991ce5.js"><link rel="prefetch" href="/assets/js/408.9806278e.js"><link rel="prefetch" href="/assets/js/409.8d9b4bb3.js"><link rel="prefetch" href="/assets/js/41.6bcfc592.js"><link rel="prefetch" href="/assets/js/410.02dee620.js"><link rel="prefetch" href="/assets/js/411.3d12d3a6.js"><link rel="prefetch" href="/assets/js/412.37a62624.js"><link rel="prefetch" href="/assets/js/413.bda7ca34.js"><link rel="prefetch" href="/assets/js/414.2abb6547.js"><link rel="prefetch" href="/assets/js/415.1d271923.js"><link rel="prefetch" href="/assets/js/416.d1b11dfe.js"><link rel="prefetch" href="/assets/js/417.fcbf07ff.js"><link rel="prefetch" href="/assets/js/418.524d40ba.js"><link rel="prefetch" href="/assets/js/419.f264e463.js"><link rel="prefetch" href="/assets/js/42.ec85a270.js"><link rel="prefetch" href="/assets/js/420.8b99e60d.js"><link rel="prefetch" href="/assets/js/421.c697d876.js"><link rel="prefetch" href="/assets/js/422.4af54ae0.js"><link rel="prefetch" href="/assets/js/423.b75f24ff.js"><link rel="prefetch" href="/assets/js/424.ea80054f.js"><link rel="prefetch" href="/assets/js/425.804b48b0.js"><link rel="prefetch" href="/assets/js/426.ffed8383.js"><link rel="prefetch" href="/assets/js/427.2040bd22.js"><link rel="prefetch" href="/assets/js/428.b878fb56.js"><link rel="prefetch" href="/assets/js/429.f81fd922.js"><link rel="prefetch" href="/assets/js/43.c174449d.js"><link rel="prefetch" href="/assets/js/430.16f328ab.js"><link rel="prefetch" href="/assets/js/431.56f11924.js"><link rel="prefetch" href="/assets/js/432.e4c77710.js"><link rel="prefetch" href="/assets/js/433.29acf14b.js"><link rel="prefetch" href="/assets/js/434.33ee22fc.js"><link rel="prefetch" href="/assets/js/435.516f7600.js"><link rel="prefetch" href="/assets/js/436.28ae526a.js"><link rel="prefetch" href="/assets/js/437.b9bac473.js"><link rel="prefetch" href="/assets/js/438.711bd934.js"><link rel="prefetch" href="/assets/js/439.fe5f28bd.js"><link rel="prefetch" href="/assets/js/44.8704338b.js"><link rel="prefetch" href="/assets/js/440.b2f48747.js"><link rel="prefetch" href="/assets/js/441.4862a724.js"><link rel="prefetch" href="/assets/js/442.751f8ae7.js"><link rel="prefetch" href="/assets/js/443.9998dbe9.js"><link rel="prefetch" href="/assets/js/444.23d3f688.js"><link rel="prefetch" href="/assets/js/445.72419f35.js"><link rel="prefetch" href="/assets/js/446.21e02b7b.js"><link rel="prefetch" href="/assets/js/447.6bd039e5.js"><link rel="prefetch" href="/assets/js/448.af29ff31.js"><link rel="prefetch" href="/assets/js/449.bbdca196.js"><link rel="prefetch" href="/assets/js/45.f8a2a3b3.js"><link rel="prefetch" href="/assets/js/450.32e470b8.js"><link rel="prefetch" href="/assets/js/451.f4c8ff6a.js"><link rel="prefetch" href="/assets/js/452.c0ec8943.js"><link rel="prefetch" href="/assets/js/453.5af475c6.js"><link rel="prefetch" href="/assets/js/454.567aa6c1.js"><link rel="prefetch" href="/assets/js/455.326072d1.js"><link rel="prefetch" href="/assets/js/456.64b88847.js"><link rel="prefetch" href="/assets/js/457.61c91559.js"><link rel="prefetch" href="/assets/js/458.4f4d43d6.js"><link rel="prefetch" href="/assets/js/459.a88891cb.js"><link rel="prefetch" href="/assets/js/460.fb9e15f6.js"><link rel="prefetch" href="/assets/js/461.998a4991.js"><link rel="prefetch" href="/assets/js/462.56ecfb03.js"><link rel="prefetch" href="/assets/js/463.582cd053.js"><link rel="prefetch" href="/assets/js/464.f12a0050.js"><link rel="prefetch" href="/assets/js/465.cc3b08a8.js"><link rel="prefetch" href="/assets/js/466.ea7e4ce2.js"><link rel="prefetch" href="/assets/js/467.58700d93.js"><link rel="prefetch" href="/assets/js/468.bb9998cd.js"><link rel="prefetch" href="/assets/js/469.232d261d.js"><link rel="prefetch" href="/assets/js/47.02516d33.js"><link rel="prefetch" href="/assets/js/470.90ab2be8.js"><link rel="prefetch" href="/assets/js/471.3652fec6.js"><link rel="prefetch" href="/assets/js/472.bc7517c9.js"><link rel="prefetch" href="/assets/js/473.27b7892f.js"><link rel="prefetch" href="/assets/js/474.0d488768.js"><link rel="prefetch" href="/assets/js/475.bc33cf17.js"><link rel="prefetch" href="/assets/js/476.76ce67eb.js"><link rel="prefetch" href="/assets/js/477.a20657f6.js"><link rel="prefetch" href="/assets/js/478.8905ef26.js"><link rel="prefetch" href="/assets/js/479.23ec3dc9.js"><link rel="prefetch" href="/assets/js/48.8d38983c.js"><link rel="prefetch" href="/assets/js/480.105bf58e.js"><link rel="prefetch" href="/assets/js/481.d62a3699.js"><link rel="prefetch" href="/assets/js/482.6cb10cdb.js"><link rel="prefetch" href="/assets/js/483.15b9ef53.js"><link rel="prefetch" href="/assets/js/484.794aff9c.js"><link rel="prefetch" href="/assets/js/485.3e6ef3cb.js"><link rel="prefetch" href="/assets/js/486.fc20eb22.js"><link rel="prefetch" href="/assets/js/487.2a4f7d47.js"><link rel="prefetch" href="/assets/js/488.24ba9af5.js"><link rel="prefetch" href="/assets/js/489.d451928e.js"><link rel="prefetch" href="/assets/js/49.bd70c59c.js"><link rel="prefetch" href="/assets/js/490.d83e4fc7.js"><link rel="prefetch" href="/assets/js/491.0210a738.js"><link rel="prefetch" href="/assets/js/492.3a69cd85.js"><link rel="prefetch" href="/assets/js/493.89d2920f.js"><link rel="prefetch" href="/assets/js/494.b7d1c15e.js"><link rel="prefetch" href="/assets/js/495.7ccfe17f.js"><link rel="prefetch" href="/assets/js/496.0d6c912a.js"><link rel="prefetch" href="/assets/js/497.087ca2c6.js"><link rel="prefetch" href="/assets/js/498.f2b3c894.js"><link rel="prefetch" href="/assets/js/499.e741f312.js"><link rel="prefetch" href="/assets/js/5.405f2620.js"><link rel="prefetch" href="/assets/js/50.9df07553.js"><link rel="prefetch" href="/assets/js/500.cb9babb9.js"><link rel="prefetch" href="/assets/js/501.63a859b6.js"><link rel="prefetch" href="/assets/js/502.f346b273.js"><link rel="prefetch" href="/assets/js/503.cdcd3de3.js"><link rel="prefetch" href="/assets/js/504.e83ec450.js"><link rel="prefetch" href="/assets/js/505.95f18293.js"><link rel="prefetch" href="/assets/js/506.02060a3c.js"><link rel="prefetch" href="/assets/js/507.859d6ae4.js"><link rel="prefetch" href="/assets/js/508.9724d886.js"><link rel="prefetch" href="/assets/js/509.e17dd53e.js"><link rel="prefetch" href="/assets/js/51.3dfc6350.js"><link rel="prefetch" href="/assets/js/510.ea0c942f.js"><link rel="prefetch" href="/assets/js/511.64a7f9a8.js"><link rel="prefetch" href="/assets/js/512.6cce418a.js"><link rel="prefetch" href="/assets/js/513.ea813fe8.js"><link rel="prefetch" href="/assets/js/514.10242470.js"><link rel="prefetch" href="/assets/js/515.5308bdf6.js"><link rel="prefetch" href="/assets/js/516.dfb113bc.js"><link rel="prefetch" href="/assets/js/517.96c71069.js"><link rel="prefetch" href="/assets/js/518.5594480e.js"><link rel="prefetch" href="/assets/js/519.91e848ae.js"><link rel="prefetch" href="/assets/js/52.dd230cd7.js"><link rel="prefetch" href="/assets/js/520.ebe69ce9.js"><link rel="prefetch" href="/assets/js/521.92b80342.js"><link rel="prefetch" href="/assets/js/522.6ce581ea.js"><link rel="prefetch" href="/assets/js/523.40b7f2f9.js"><link rel="prefetch" href="/assets/js/524.4ef256d3.js"><link rel="prefetch" href="/assets/js/525.19741e4a.js"><link rel="prefetch" href="/assets/js/526.e5de1675.js"><link rel="prefetch" href="/assets/js/527.9a79cd42.js"><link rel="prefetch" href="/assets/js/528.72732eb8.js"><link rel="prefetch" href="/assets/js/529.2ea03e45.js"><link rel="prefetch" href="/assets/js/53.a349c565.js"><link rel="prefetch" href="/assets/js/530.5d1103e7.js"><link rel="prefetch" href="/assets/js/531.82b032d6.js"><link rel="prefetch" href="/assets/js/532.12ee4beb.js"><link rel="prefetch" href="/assets/js/533.db9a90f7.js"><link rel="prefetch" href="/assets/js/534.fe139db4.js"><link rel="prefetch" href="/assets/js/535.056a6fbb.js"><link rel="prefetch" href="/assets/js/536.6bf85c15.js"><link rel="prefetch" href="/assets/js/537.6e2e1ccf.js"><link rel="prefetch" href="/assets/js/538.54eddb3b.js"><link rel="prefetch" href="/assets/js/539.6f00a207.js"><link rel="prefetch" href="/assets/js/54.e292b52f.js"><link rel="prefetch" href="/assets/js/540.9c956205.js"><link rel="prefetch" href="/assets/js/541.50f41228.js"><link rel="prefetch" href="/assets/js/542.a2b1879e.js"><link rel="prefetch" href="/assets/js/543.4e5e17c9.js"><link rel="prefetch" href="/assets/js/544.63d85227.js"><link rel="prefetch" href="/assets/js/545.c3923644.js"><link rel="prefetch" href="/assets/js/546.e64ad073.js"><link rel="prefetch" href="/assets/js/547.35a8752d.js"><link rel="prefetch" href="/assets/js/548.b62a1348.js"><link rel="prefetch" href="/assets/js/549.369e2ea0.js"><link rel="prefetch" href="/assets/js/55.21bb2983.js"><link rel="prefetch" href="/assets/js/550.b4632248.js"><link rel="prefetch" href="/assets/js/551.18f1879c.js"><link rel="prefetch" href="/assets/js/552.162e63cd.js"><link rel="prefetch" href="/assets/js/553.6998130e.js"><link rel="prefetch" href="/assets/js/554.89126c3d.js"><link rel="prefetch" href="/assets/js/555.a5f63b8a.js"><link rel="prefetch" href="/assets/js/556.35381cef.js"><link rel="prefetch" href="/assets/js/557.ceeecf52.js"><link rel="prefetch" href="/assets/js/558.253e6e4f.js"><link rel="prefetch" href="/assets/js/559.5cfbb773.js"><link rel="prefetch" href="/assets/js/56.5382d6b4.js"><link rel="prefetch" href="/assets/js/560.cca52f22.js"><link rel="prefetch" href="/assets/js/561.ea8d1141.js"><link rel="prefetch" href="/assets/js/562.c32e7b96.js"><link rel="prefetch" href="/assets/js/563.9bdd42e7.js"><link rel="prefetch" href="/assets/js/564.b3b87ec0.js"><link rel="prefetch" href="/assets/js/565.4be0d0f7.js"><link rel="prefetch" href="/assets/js/566.9f379d12.js"><link rel="prefetch" href="/assets/js/567.261e3181.js"><link rel="prefetch" href="/assets/js/568.4229e365.js"><link rel="prefetch" href="/assets/js/569.e662c167.js"><link rel="prefetch" href="/assets/js/57.8129f7e0.js"><link rel="prefetch" href="/assets/js/570.97ff6423.js"><link rel="prefetch" href="/assets/js/571.de1377cd.js"><link rel="prefetch" href="/assets/js/572.48b8400b.js"><link rel="prefetch" href="/assets/js/573.8251ebaf.js"><link rel="prefetch" href="/assets/js/574.ec3d6c1e.js"><link rel="prefetch" href="/assets/js/575.b0d429a1.js"><link rel="prefetch" href="/assets/js/576.98ce9170.js"><link rel="prefetch" href="/assets/js/577.85fc2017.js"><link rel="prefetch" href="/assets/js/578.1393ac7f.js"><link rel="prefetch" href="/assets/js/579.1340e178.js"><link rel="prefetch" href="/assets/js/58.85ac2740.js"><link rel="prefetch" href="/assets/js/580.a5979445.js"><link rel="prefetch" href="/assets/js/581.effdc269.js"><link rel="prefetch" href="/assets/js/582.13276063.js"><link rel="prefetch" href="/assets/js/583.357a2443.js"><link rel="prefetch" href="/assets/js/584.338ef731.js"><link rel="prefetch" href="/assets/js/585.87932741.js"><link rel="prefetch" href="/assets/js/586.b1d6e000.js"><link rel="prefetch" href="/assets/js/587.ed5b8377.js"><link rel="prefetch" href="/assets/js/588.16d2c418.js"><link rel="prefetch" href="/assets/js/589.c96fd7fa.js"><link rel="prefetch" href="/assets/js/59.0b225757.js"><link rel="prefetch" href="/assets/js/590.1a06b2a0.js"><link rel="prefetch" href="/assets/js/591.0efd886c.js"><link rel="prefetch" href="/assets/js/592.b22d0ef5.js"><link rel="prefetch" href="/assets/js/593.84ed6ebe.js"><link rel="prefetch" href="/assets/js/594.cd721b88.js"><link rel="prefetch" href="/assets/js/595.2400817a.js"><link rel="prefetch" href="/assets/js/596.f2c512d1.js"><link rel="prefetch" href="/assets/js/597.df10ec57.js"><link rel="prefetch" href="/assets/js/598.61ef6a7d.js"><link rel="prefetch" href="/assets/js/599.0bebb562.js"><link rel="prefetch" href="/assets/js/6.29d112b1.js"><link rel="prefetch" href="/assets/js/60.3bbab51d.js"><link rel="prefetch" href="/assets/js/600.1ea7596f.js"><link rel="prefetch" href="/assets/js/601.f2642bb3.js"><link rel="prefetch" href="/assets/js/602.400cc987.js"><link rel="prefetch" href="/assets/js/603.db77d173.js"><link rel="prefetch" href="/assets/js/604.0ffa30ae.js"><link rel="prefetch" href="/assets/js/605.32ca9607.js"><link rel="prefetch" href="/assets/js/606.8c1e5683.js"><link rel="prefetch" href="/assets/js/607.9c9463ef.js"><link rel="prefetch" href="/assets/js/608.d5efa77e.js"><link rel="prefetch" href="/assets/js/609.5bbffb7d.js"><link rel="prefetch" href="/assets/js/61.f7301486.js"><link rel="prefetch" href="/assets/js/610.5b0fc9da.js"><link rel="prefetch" href="/assets/js/611.bb8058c9.js"><link rel="prefetch" href="/assets/js/612.b0788f43.js"><link rel="prefetch" href="/assets/js/613.49511e65.js"><link rel="prefetch" href="/assets/js/614.fae3eacf.js"><link rel="prefetch" href="/assets/js/615.359e5899.js"><link rel="prefetch" href="/assets/js/616.905132f4.js"><link rel="prefetch" href="/assets/js/617.6c8c594e.js"><link rel="prefetch" href="/assets/js/618.6ac4f3ff.js"><link rel="prefetch" href="/assets/js/619.411a0c14.js"><link rel="prefetch" href="/assets/js/62.9aeede84.js"><link rel="prefetch" href="/assets/js/620.56155724.js"><link rel="prefetch" href="/assets/js/621.149d7933.js"><link rel="prefetch" href="/assets/js/622.f0c9bc08.js"><link rel="prefetch" href="/assets/js/623.e0989fbe.js"><link rel="prefetch" href="/assets/js/624.80b1f6a9.js"><link rel="prefetch" href="/assets/js/625.a0a392c4.js"><link rel="prefetch" href="/assets/js/626.56fd4e8a.js"><link rel="prefetch" href="/assets/js/627.264e7313.js"><link rel="prefetch" href="/assets/js/628.7a868b19.js"><link rel="prefetch" href="/assets/js/629.e7e15da1.js"><link rel="prefetch" href="/assets/js/63.4df55c8b.js"><link rel="prefetch" href="/assets/js/630.998c9b61.js"><link rel="prefetch" href="/assets/js/631.69aa049c.js"><link rel="prefetch" href="/assets/js/632.da3882c1.js"><link rel="prefetch" href="/assets/js/633.0d49adf0.js"><link rel="prefetch" href="/assets/js/634.f9984ede.js"><link rel="prefetch" href="/assets/js/635.f0439f65.js"><link rel="prefetch" href="/assets/js/636.54de4194.js"><link rel="prefetch" href="/assets/js/637.55d1c226.js"><link rel="prefetch" href="/assets/js/638.2a9a510f.js"><link rel="prefetch" href="/assets/js/639.8bec360e.js"><link rel="prefetch" href="/assets/js/64.7f3e5e81.js"><link rel="prefetch" href="/assets/js/640.30d7f96e.js"><link rel="prefetch" href="/assets/js/641.68100098.js"><link rel="prefetch" href="/assets/js/642.4b793817.js"><link rel="prefetch" href="/assets/js/643.d86a81ea.js"><link rel="prefetch" href="/assets/js/644.76327ea2.js"><link rel="prefetch" href="/assets/js/645.0ac6a923.js"><link rel="prefetch" href="/assets/js/646.cd92f728.js"><link rel="prefetch" href="/assets/js/647.f2c624e1.js"><link rel="prefetch" href="/assets/js/648.c8f3b955.js"><link rel="prefetch" href="/assets/js/649.6370753b.js"><link rel="prefetch" href="/assets/js/65.2beeae9b.js"><link rel="prefetch" href="/assets/js/650.afe31909.js"><link rel="prefetch" href="/assets/js/651.87971ec0.js"><link rel="prefetch" href="/assets/js/652.0adf10a6.js"><link rel="prefetch" href="/assets/js/653.1f655726.js"><link rel="prefetch" href="/assets/js/654.53e24c7c.js"><link rel="prefetch" href="/assets/js/655.c95a66ea.js"><link rel="prefetch" href="/assets/js/656.38b5a5ea.js"><link rel="prefetch" href="/assets/js/657.3167aa94.js"><link rel="prefetch" href="/assets/js/658.7c40ff62.js"><link rel="prefetch" href="/assets/js/659.5d2b9b54.js"><link rel="prefetch" href="/assets/js/66.44b214db.js"><link rel="prefetch" href="/assets/js/660.96a8da9e.js"><link rel="prefetch" href="/assets/js/661.4de3b6c1.js"><link rel="prefetch" href="/assets/js/662.7d9bf181.js"><link rel="prefetch" href="/assets/js/663.4ccaf40a.js"><link rel="prefetch" href="/assets/js/664.7ab4fa53.js"><link rel="prefetch" href="/assets/js/665.32245d26.js"><link rel="prefetch" href="/assets/js/666.e6617151.js"><link rel="prefetch" href="/assets/js/667.fb3b0547.js"><link rel="prefetch" href="/assets/js/668.3d1b2e36.js"><link rel="prefetch" href="/assets/js/669.b769905f.js"><link rel="prefetch" href="/assets/js/67.c31aaacf.js"><link rel="prefetch" href="/assets/js/670.88ed3af3.js"><link rel="prefetch" href="/assets/js/671.1aff6bfe.js"><link rel="prefetch" href="/assets/js/672.c90888f7.js"><link rel="prefetch" href="/assets/js/673.81241fdc.js"><link rel="prefetch" href="/assets/js/674.838a424d.js"><link rel="prefetch" href="/assets/js/675.603ac896.js"><link rel="prefetch" href="/assets/js/676.ff44b5dc.js"><link rel="prefetch" href="/assets/js/677.41a8087a.js"><link rel="prefetch" href="/assets/js/678.f0eb8d04.js"><link rel="prefetch" href="/assets/js/679.db78199e.js"><link rel="prefetch" href="/assets/js/68.08607c89.js"><link rel="prefetch" href="/assets/js/680.8fded9d4.js"><link rel="prefetch" href="/assets/js/681.0b019dfd.js"><link rel="prefetch" href="/assets/js/682.746e9190.js"><link rel="prefetch" href="/assets/js/683.d5c00845.js"><link rel="prefetch" href="/assets/js/684.b3207cad.js"><link rel="prefetch" href="/assets/js/685.d78f18ba.js"><link rel="prefetch" href="/assets/js/686.5aaecd19.js"><link rel="prefetch" href="/assets/js/687.821a06f4.js"><link rel="prefetch" href="/assets/js/688.8bbc1890.js"><link rel="prefetch" href="/assets/js/689.79b49e8c.js"><link rel="prefetch" href="/assets/js/69.509245d6.js"><link rel="prefetch" href="/assets/js/690.fa62f9dd.js"><link rel="prefetch" href="/assets/js/691.d3eb1a60.js"><link rel="prefetch" href="/assets/js/692.738f14bb.js"><link rel="prefetch" href="/assets/js/693.e6a497a2.js"><link rel="prefetch" href="/assets/js/694.6eea1c54.js"><link rel="prefetch" href="/assets/js/695.88e6acee.js"><link rel="prefetch" href="/assets/js/696.de10297f.js"><link rel="prefetch" href="/assets/js/697.96d04062.js"><link rel="prefetch" href="/assets/js/698.200cc84f.js"><link rel="prefetch" href="/assets/js/699.f11fc627.js"><link rel="prefetch" href="/assets/js/7.c16198b8.js"><link rel="prefetch" href="/assets/js/70.5f6285b1.js"><link rel="prefetch" href="/assets/js/700.93d48f59.js"><link rel="prefetch" href="/assets/js/701.b861f29a.js"><link rel="prefetch" href="/assets/js/702.dc82e05c.js"><link rel="prefetch" href="/assets/js/703.625ce87c.js"><link rel="prefetch" href="/assets/js/704.005a0a7c.js"><link rel="prefetch" href="/assets/js/705.16ad9230.js"><link rel="prefetch" href="/assets/js/706.4eead30a.js"><link rel="prefetch" href="/assets/js/707.730306ce.js"><link rel="prefetch" href="/assets/js/708.e37e743a.js"><link rel="prefetch" href="/assets/js/709.f2144f52.js"><link rel="prefetch" href="/assets/js/71.d5d0dae5.js"><link rel="prefetch" href="/assets/js/710.ee9d9b17.js"><link rel="prefetch" href="/assets/js/711.2813c338.js"><link rel="prefetch" href="/assets/js/712.e801bce4.js"><link rel="prefetch" href="/assets/js/713.21fc267c.js"><link rel="prefetch" href="/assets/js/714.4ec35525.js"><link rel="prefetch" href="/assets/js/715.fdc3cc84.js"><link rel="prefetch" href="/assets/js/716.324932ad.js"><link rel="prefetch" href="/assets/js/717.a072a66f.js"><link rel="prefetch" href="/assets/js/718.575e0305.js"><link rel="prefetch" href="/assets/js/719.5fdd55de.js"><link rel="prefetch" href="/assets/js/72.25648231.js"><link rel="prefetch" href="/assets/js/720.61477f23.js"><link rel="prefetch" href="/assets/js/721.c8bdab00.js"><link rel="prefetch" href="/assets/js/722.9255f385.js"><link rel="prefetch" href="/assets/js/723.f27792a4.js"><link rel="prefetch" href="/assets/js/724.cd504f88.js"><link rel="prefetch" href="/assets/js/725.55c845fa.js"><link rel="prefetch" href="/assets/js/726.bb49a9db.js"><link rel="prefetch" href="/assets/js/727.53d587fe.js"><link rel="prefetch" href="/assets/js/728.86972387.js"><link rel="prefetch" href="/assets/js/729.02fa0263.js"><link rel="prefetch" href="/assets/js/73.29902c1f.js"><link rel="prefetch" href="/assets/js/730.817156d1.js"><link rel="prefetch" href="/assets/js/731.6f5d6735.js"><link rel="prefetch" href="/assets/js/732.9a5ff781.js"><link rel="prefetch" href="/assets/js/733.bcb13916.js"><link rel="prefetch" href="/assets/js/734.11482b19.js"><link rel="prefetch" href="/assets/js/735.8c0d62f3.js"><link rel="prefetch" href="/assets/js/736.06465705.js"><link rel="prefetch" href="/assets/js/737.79741d87.js"><link rel="prefetch" href="/assets/js/738.cad12ff9.js"><link rel="prefetch" href="/assets/js/739.cb09e552.js"><link rel="prefetch" href="/assets/js/74.bcf666a0.js"><link rel="prefetch" href="/assets/js/740.029b1950.js"><link rel="prefetch" href="/assets/js/741.b937216a.js"><link rel="prefetch" href="/assets/js/742.ec02c706.js"><link rel="prefetch" href="/assets/js/743.70a96283.js"><link rel="prefetch" href="/assets/js/744.909b870c.js"><link rel="prefetch" href="/assets/js/745.80defb2d.js"><link rel="prefetch" href="/assets/js/746.fb972248.js"><link rel="prefetch" href="/assets/js/747.1a7b52fd.js"><link rel="prefetch" href="/assets/js/748.036f5d16.js"><link rel="prefetch" href="/assets/js/749.bd9a413d.js"><link rel="prefetch" href="/assets/js/75.23c5a54d.js"><link rel="prefetch" href="/assets/js/750.3f1ae8f5.js"><link rel="prefetch" href="/assets/js/751.8897bc9f.js"><link rel="prefetch" href="/assets/js/752.9b387659.js"><link rel="prefetch" href="/assets/js/753.f411ce21.js"><link rel="prefetch" href="/assets/js/754.26def684.js"><link rel="prefetch" href="/assets/js/755.923aff62.js"><link rel="prefetch" href="/assets/js/756.9965743a.js"><link rel="prefetch" href="/assets/js/757.0c6bbbfd.js"><link rel="prefetch" href="/assets/js/758.a830f8b1.js"><link rel="prefetch" href="/assets/js/759.987cad77.js"><link rel="prefetch" href="/assets/js/76.f54f3d4f.js"><link rel="prefetch" href="/assets/js/760.9f2652a0.js"><link rel="prefetch" href="/assets/js/761.df01a0ee.js"><link rel="prefetch" href="/assets/js/762.e0c05a1a.js"><link rel="prefetch" href="/assets/js/763.da8a60bd.js"><link rel="prefetch" href="/assets/js/764.9f2a2830.js"><link rel="prefetch" href="/assets/js/765.44e61161.js"><link rel="prefetch" href="/assets/js/766.cd7da8c1.js"><link rel="prefetch" href="/assets/js/767.6ea1fea2.js"><link rel="prefetch" href="/assets/js/768.91529b8f.js"><link rel="prefetch" href="/assets/js/769.194d7a3e.js"><link rel="prefetch" href="/assets/js/77.3d43a163.js"><link rel="prefetch" href="/assets/js/770.227fd5b9.js"><link rel="prefetch" href="/assets/js/771.44d5e37e.js"><link rel="prefetch" href="/assets/js/772.234d9bf6.js"><link rel="prefetch" href="/assets/js/773.ff1dfb6a.js"><link rel="prefetch" href="/assets/js/774.d401364f.js"><link rel="prefetch" href="/assets/js/775.37a7cf41.js"><link rel="prefetch" href="/assets/js/776.0cd10853.js"><link rel="prefetch" href="/assets/js/777.599a3a48.js"><link rel="prefetch" href="/assets/js/778.eef27a95.js"><link rel="prefetch" href="/assets/js/779.29351199.js"><link rel="prefetch" href="/assets/js/78.fd0780ac.js"><link rel="prefetch" href="/assets/js/780.74caed94.js"><link rel="prefetch" href="/assets/js/781.ee0fa9b5.js"><link rel="prefetch" href="/assets/js/782.7cffed09.js"><link rel="prefetch" href="/assets/js/783.7f01f518.js"><link rel="prefetch" href="/assets/js/784.5f65e3d7.js"><link rel="prefetch" href="/assets/js/785.d7e13880.js"><link rel="prefetch" href="/assets/js/786.6110d12f.js"><link rel="prefetch" href="/assets/js/787.334a5cdd.js"><link rel="prefetch" href="/assets/js/788.f261bc71.js"><link rel="prefetch" href="/assets/js/789.b6d74f7d.js"><link rel="prefetch" href="/assets/js/79.7b5d6224.js"><link rel="prefetch" href="/assets/js/790.fa948ec4.js"><link rel="prefetch" href="/assets/js/791.22080013.js"><link rel="prefetch" href="/assets/js/792.31ce806c.js"><link rel="prefetch" href="/assets/js/793.9fd0c56f.js"><link rel="prefetch" href="/assets/js/794.44a8cd9c.js"><link rel="prefetch" href="/assets/js/795.9f8346e5.js"><link rel="prefetch" href="/assets/js/796.0de9c7a1.js"><link rel="prefetch" href="/assets/js/797.83ac32a6.js"><link rel="prefetch" href="/assets/js/798.393fc81d.js"><link rel="prefetch" href="/assets/js/799.c1fb3981.js"><link rel="prefetch" href="/assets/js/8.3275ed06.js"><link rel="prefetch" href="/assets/js/80.df3f0a1f.js"><link rel="prefetch" href="/assets/js/800.2832adeb.js"><link rel="prefetch" href="/assets/js/801.04c58fc4.js"><link rel="prefetch" href="/assets/js/81.3d90ef6b.js"><link rel="prefetch" href="/assets/js/82.2d42448d.js"><link rel="prefetch" href="/assets/js/83.900b4de2.js"><link rel="prefetch" href="/assets/js/84.ff570f67.js"><link rel="prefetch" href="/assets/js/85.e3b3af39.js"><link rel="prefetch" href="/assets/js/86.17b5aedc.js"><link rel="prefetch" href="/assets/js/87.f931d1d6.js"><link rel="prefetch" href="/assets/js/88.d55863cd.js"><link rel="prefetch" href="/assets/js/89.15a9a6d7.js"><link rel="prefetch" href="/assets/js/9.04948a9d.js"><link rel="prefetch" href="/assets/js/90.22696aa9.js"><link rel="prefetch" href="/assets/js/91.f1bd8a2e.js"><link rel="prefetch" href="/assets/js/92.85733094.js"><link rel="prefetch" href="/assets/js/93.59bacfd7.js"><link rel="prefetch" href="/assets/js/94.a5f9b7a0.js"><link rel="prefetch" href="/assets/js/95.be52d65a.js"><link rel="prefetch" href="/assets/js/96.0b76ba8e.js"><link rel="prefetch" href="/assets/js/97.28183cd4.js"><link rel="prefetch" href="/assets/js/98.2d22829c.js"><link rel="prefetch" href="/assets/js/99.ed602a20.js">
    <link rel="stylesheet" href="/assets/css/0.styles.a3df589e.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><!----> <span class="site-name">AJ</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/" class="nav-link">主页</a></div><div class="nav-item"><a href="/op/" class="nav-link">Devops</a></div><div class="nav-item"><a href="/golang/" class="nav-link">Go</a></div><div class="nav-item"><a href="/go-block/" class="nav-link router-link-active">区块链</a></div><div class="nav-item"><a href="/k8s/" class="nav-link">k8s</a></div><div class="nav-item"><a href="/about.html" class="nav-link">关于我</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="更多" class="dropdown-title"><span class="title">更多</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/go-learning/" class="nav-link">go-learning</a></li><li class="dropdown-item"><!----> <a href="/post/flutter-guide/" class="nav-link">flutter</a></li><li class="dropdown-item"><!----> <a href="/mysql/" class="nav-link">mysql</a></li><li class="dropdown-item"><!----> <a href="/python/" class="nav-link">python</a></li></ul></div></div> <a href="https://github.com/ChinaArJun" target="_blank" rel="noopener noreferrer" class="repo-link">
    GitHub
    <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/" class="nav-link">主页</a></div><div class="nav-item"><a href="/op/" class="nav-link">Devops</a></div><div class="nav-item"><a href="/golang/" class="nav-link">Go</a></div><div class="nav-item"><a href="/go-block/" class="nav-link router-link-active">区块链</a></div><div class="nav-item"><a href="/k8s/" class="nav-link">k8s</a></div><div class="nav-item"><a href="/about.html" class="nav-link">关于我</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="更多" class="dropdown-title"><span class="title">更多</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/go-learning/" class="nav-link">go-learning</a></li><li class="dropdown-item"><!----> <a href="/post/flutter-guide/" class="nav-link">flutter</a></li><li class="dropdown-item"><!----> <a href="/mysql/" class="nav-link">mysql</a></li><li class="dropdown-item"><!----> <a href="/python/" class="nav-link">python</a></li></ul></div></div> <a href="https://github.com/ChinaArJun" target="_blank" rel="noopener noreferrer" class="repo-link">
    GitHub
    <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></nav> <div></div> <div style="padding-left:1.5rem;"><div></div></div> <ul class="sidebar-links"><li><section class="sidebar-group depth-0"><p class="sidebar-heading open"><span>区块链基础</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/go-block/blockchain/encryption-expand.html" class="sidebar-link">常见的密码技术</a></li><li><a href="/go-block/blockchain/encryption.html" aria-current="page" class="active sidebar-link">密码学安全</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/go-block/blockchain/encryption.html#_01-对称加密" class="sidebar-link">01 - 对称加密</a></li><li class="sidebar-sub-header"><a href="/go-block/blockchain/encryption.html#_02-非对称加密" class="sidebar-link">02 - 非对称加密</a></li><li class="sidebar-sub-header"><a href="/go-block/blockchain/encryption.html#_03-消息认证码" class="sidebar-link">03 - 消息认证码</a></li><li class="sidebar-sub-header"><a href="/go-block/blockchain/encryption.html#_04-数字签名" class="sidebar-link">04 - 数字签名</a></li><li class="sidebar-sub-header"><a href="/go-block/blockchain/encryption.html#_05-证书" class="sidebar-link">05 - 证书</a></li></ul></li><li><a href="/go-block/blockchain/ethereum.html" class="sidebar-link">以太坊智能合约</a></li><li><a href="/go-block/blockchain/hyperledgerfabric.html" class="sidebar-link">hyperledger fabric</a></li></ul></section></li><li><section class="sidebar-group depth-0"><p class="sidebar-heading"><span>Hyperledger Fabric 1.2</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/go-block/fabric/1搭建网络-纯手动.html" class="sidebar-link">1搭建网络-纯手动</a></li><li><a href="/go-block/fabric/1环境搭建.html" class="sidebar-link">1环境搭建</a></li><li><a href="/go-block/fabric/2Fabric介绍.html" class="sidebar-link">2Fabric介绍</a></li><li><a href="/go-block/fabric/3Fabric核心模块.html" class="sidebar-link">3Fabric核心模块</a></li><li><a href="/go-block/fabric/4网络搭建-脚本.html" class="sidebar-link">4网络搭建-脚本</a></li><li><a href="/go-block/fabric/5智能合约.html" class="sidebar-link">5智能合约</a></li><li><a href="/go-block/fabric/6Fabric账号.html" class="sidebar-link">6Fabric账号</a></li><li><a href="/go-block/fabric/7Solo多机多节点部署.html" class="sidebar-link">7Solo多机多节点部署</a></li><li><a href="/go-block/fabric/8Kafka多机多节点部署.html" class="sidebar-link">8Kafka多机多节点部署</a></li></ul></section></li><li><section class="sidebar-group depth-0"><p class="sidebar-heading"><span>Hyperledger Fabric 2.X</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/go-block/fabric2.x/" class="sidebar-link">2.X目录</a></li></ul></section></li></ul> </aside> <!----> <!----> <main class="page"><div class="theme-default-content" style="margin-bottom:-5rem;"><div class="bar"><div class="bar-intro"><div class="text">
      流逝的是岁月，不变的是情怀.
        </div> <div class="text">
      坚持学习，是为了成就更好的自己. <br></div> <div>公众号[中关村程序员]</div></div></div> <!----></div> <div class="theme-default-content content__default"><h2 id="_01-对称加密"><a href="#_01-对称加密" class="header-anchor">#</a> 01 - 对称加密</h2> <h3 id="_1-1-基础知识点"><a href="#_1-1-基础知识点" class="header-anchor">#</a> 1.1 基础知识点</h3> <ol><li><p>知识点大纲介绍</p> <ul><li>密码的基础概念</li> <li>对称加密</li> <li>非对称加密</li> <li>单向散列函数
<ul><li>哈希函数</li></ul></li> <li>消息认证码</li> <li>数字签名</li> <li>证书</li> <li>ssl/tls - https</li></ul></li> <li><p>为什么要加密, 以及解决方案</p> <p>保证数据安全</p></li> <li><p>加密三要素</p> <ul><li>明文/密文</li> <li>秘钥
<ul><li>定长的字符串</li> <li>需要根据加密算法确定其长度</li></ul></li> <li>算法
<ul><li>加密算法</li> <li>解密算法</li> <li>加密算法和解密算法有可能是互逆的, 也有可能相同</li></ul></li></ul></li> <li><p>常用的两种加密方式</p> <ul><li>对称加密
<ul><li>秘钥: 加密解密使用的是同一个秘钥, 秘钥有一个</li> <li>特点
<ul><li>双方向保证机密性</li> <li>加密效率高, 适合加密大数据, 大文件</li> <li>加密强度不高, 相对于非对称加密</li></ul></li></ul></li> <li>非对称加密
<ul><li>秘钥: 加密解密使用的不同的秘钥, 秘钥有两个, 需要使用秘钥生成算法, 得到密钥对
<ul><li>公钥 - 可以公开的秘钥
<ul><li>公钥加密数据, 解密需要使用私钥</li></ul></li> <li>私钥 - 需要妥善保管的秘钥, 知道的人越少越好
<ul><li>私钥加密, 公钥解密</li></ul></li></ul></li> <li>特点:
<ul><li>数据的机密性只能单方向保证</li> <li>加密效率低, 适合加密少量数据</li> <li>加密强度高, 相对于对称加密</li></ul></li></ul></li></ul></li> <li><p>凯撒密码</p> <p>恺撒密码（Caesar cipher）是一种相传尤利乌斯·恺撒曾使用过的密码。恺撒于公元前100年左右诞生于古罗马，是一位著名的军事统帅。</p> <blockquote><p><font color="red">恺撤密码是通过将明文中所使用的字母表按照一定的字数“平移”来进行加密的</font>。</p></blockquote> <p><img src="http://static.zhequtao.com/study/04mimaxue/day01/1538906583082.png" alt="1538906583082"></p> <ul><li><p>凯撒密码加解密公式</p> <ul><li>加密</li></ul> <p><img src="http://static.zhequtao.com/study/04mimaxue/day01/513169b7dcabfc4de6d4fcbc03e613434244e917.svg" alt=""></p> <ul><li><p>解密</p> <p><img src="http://static.zhequtao.com/study/04mimaxue/day01/110911f42b858bdf1bec629ae41b5b88b00859e2.svg" alt=""></p></li></ul></li> <li><p>凯撒密码中的加密三要素</p> <ul><li>明文/密文
<ul><li>明文: 小写字母表中的数据</li> <li>密文: 大写字母表中的数据</li></ul></li> <li>秘钥
<ul><li>按照上图秘钥为3</li></ul></li> <li>算法
<ul><li>加密: +3</li> <li>解密: -3</li></ul></li></ul></li> <li><p>凯撒密码的安全性</p> <p>不安全</p></li></ul></li> <li><p>密码信息安全常识</p> <ul><li>不要使用保密的密码算法（普通公司和个人）</li> <li>使用低强度的密码比不进行任何加密更危险</li> <li>任何密码总有一天都会被破解</li> <li>密码只是信息安全的一部分</li></ul></li> <li><p>密码信息威胁</p> <p><img src="http://static.zhequtao.com/study/04mimaxue/day01/1538907602932.png" alt="1538907602932"></p> <p>思考：信息安全处理必须要具备哪些特性？</p></li></ol> <h3 id="_1-2-对称加密"><a href="#_1-2-对称加密" class="header-anchor">#</a> 1.2 对称加密</h3> <blockquote><p>以分组为单位进行处理的密码算法称为<strong>分组密码（blockcipher）</strong></p></blockquote> <ol><li><p>编码的概念</p> <p>G = 1024m</p> <p>m = 1024kbyte</p> <p>byte  = 8bit</p> <p>bit 0/1</p> <blockquote><p>计算机的操作对象并不是文字，而是由0和1排列而成的<strong>比特序列</strong>。</p> <p>将现实世界中的东西映射为比特序列的操作称为<strong>编码（encoding）</strong>。</p> <p>加密 -&gt; 编码</p> <p>解密 -&gt; 解码</p></blockquote> <p>hello world -&gt; 比特序列</p> <p>h -&gt; int 104 -&gt;</p></li> <li><p>DES   --   Data Encryption Standard</p> <ul><li>现在使用DES方式加密，数据还安全吗？
<ul><li>不安全, 已经被破解了</li></ul></li> <li>是不是分组密码？
<ul><li>是, 先对数据进行分组, 然后在加密或解密</li></ul></li> <li>DES的分组长度?
<ul><li>8byte == 64bit</li></ul></li> <li>DES的秘钥长度?
<ul><li>56bit秘钥长度+8bit错误检测标志位 = 64bit == 8byte</li></ul></li></ul></li> <li><p>3DES   --   Triple-DES</p> <ul><li>3DES安全吗?
<ul><li>安全, 但是效率低</li></ul></li> <li>算法描述?
<ul><li>进行了3次des加密</li></ul></li> <li>是不是分组密码?
<ul><li>是</li></ul></li> <li>3DES分组长度?
<ul><li>8字节</li></ul></li> <li>3DES秘钥长度?
<ul><li>24字节, 在算法内部会被平均分成3份</li></ul></li> <li>3DES加密过程?
<ul><li>秘钥1 -&gt; 加密, 秘钥2 -&gt; 解密, 秘钥3 -&gt; 加密</li></ul></li> <li>3DES解密过程?
<ul><li>秘钥1 -&gt; 解密, 秘钥2 -&gt; 加密, 秘钥3 -&gt; 解密</li></ul></li></ul></li> <li><p>AES   --   Advanced Encryption Standard</p> <ul><li>AES安全吗?
<ul><li>安全, 效率高, 推荐使用的</li></ul></li> <li>是不是分组密码?
<ul><li>是</li></ul></li> <li>AES分组长度?
<ul><li>128bit = 16字节</li></ul></li> <li>AES秘钥长度?
<ul><li>128bit = 16字节</li> <li>192bit = 24字节</li> <li>256bit = 32字节</li> <li>go中的秘钥长度只能是16字节</li></ul></li></ul></li></ol> <h3 id="_1-3-分组密码的模式"><a href="#_1-3-分组密码的模式" class="header-anchor">#</a> 1.3 分组密码的模式</h3> <ol><li><p>按位异或</p> <ul><li><p>第一步需要将数据转换为二进制</p></li> <li><p>按位异或操作符: ^</p></li> <li><p>两个标志位进行按位异或操作:</p> <ul><li>相同为0, 不同为1</li></ul></li> <li><p>举例:</p> <div class="language-go extra-class"><pre class="language-go"><code><span class="token number">1</span> <span class="token number">0</span> <span class="token number">0</span> <span class="token number">0</span>   <span class="token operator">--</span><span class="token operator">--</span><span class="token operator">&gt;</span> <span class="token number">8</span>
<span class="token number">1</span> <span class="token number">0</span> <span class="token number">1</span> <span class="token number">1</span>   <span class="token operator">--</span><span class="token operator">--</span><span class="token operator">&gt;</span> <span class="token number">11</span>
<span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">-</span>按位异或一次
<span class="token number">0</span> <span class="token number">0</span> <span class="token number">1</span> <span class="token number">1</span>   <span class="token operator">--</span><span class="token operator">--</span><span class="token operator">&gt;</span>  <span class="token number">3</span>
<span class="token number">1</span> <span class="token number">0</span> <span class="token number">1</span> <span class="token number">1</span>   <span class="token operator">--</span><span class="token operator">--</span><span class="token operator">&gt;</span> <span class="token number">11</span>
<span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">-</span>按位异或两侧
<span class="token number">1</span> <span class="token number">0</span> <span class="token number">0</span> <span class="token number">0</span>   <span class="token operator">--</span><span class="token operator">--</span><span class="token operator">-</span><span class="token operator">&gt;</span> <span class="token number">8</span>
<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span>
a <span class="token operator">=</span> <span class="token number">8</span>
b <span class="token operator">=</span> <span class="token number">11</span>
a 和 b按位异或<span class="token number">1</span>次 <span class="token operator">==</span><span class="token operator">&gt;</span> 加密
得到的结果再次和 b 按位异或 <span class="token operator">==</span><span class="token operator">=</span><span class="token operator">&gt;</span> 解密
</code></pre></div></li></ul></li> <li><p>ECB - Electronic Code Book, 电子密码本模式</p> <ul><li>特点: 简单, 效率高, 密文有规律, 容易被破解</li> <li>最后一个明文分组必须要填充
<ul><li>des/3des -&gt; 最后一个分组填充满8字节</li> <li>aes -&gt; 最后一个分组填充满16字节</li></ul></li> <li>不需要初始化向量</li></ul></li> <li><p>CBC - Cipher Block Chaining, 密码块链模式</p> <ul><li>特点: 密文没有规律, 经常使用的加密方式</li> <li>最后一个明文分组需要填充
<ul><li>des/3des -&gt; 最后一个分组填充满8字节</li> <li>aes -&gt; 最后一个分组填充满16字节</li></ul></li> <li>需要一个初始化向量 - 一个数组
<ul><li>数组的长度: 与明文分组相等</li> <li>数据来源: 负责加密的人的提供的</li> <li>加解密使用的初始化向量值必须相同</li></ul></li></ul></li> <li><p>CFB - Cipher FeedBack, 密文反馈模式</p> <ul><li>特点: 密文没有规律,  明文分组是和一个数据流进行的按位异或操作, 最终生成了密文</li> <li>需要一个初始化向量 - 一个数组
<ul><li>数组的长度: 与明文分组相等</li> <li>数据来源: 负责加密的人的提供的</li> <li>加解密使用的初始化向量值必须相同</li></ul></li> <li>不需要填充</li></ul></li> <li><p>OFB - Output-Feedback, 输出反馈模式</p> <ul><li>特点: 密文没有规律,  明文分组是和一个数据流进行的按位异或操作, 最终生成了密文</li> <li>需要一个初始化向量 - 一个数组
<ul><li>数组的长度: 与明文分组相等</li> <li>数据来源: 负责加密的人的提供的</li> <li>加解密使用的初始化向量值必须相同</li></ul></li> <li>不需要填充</li></ul></li> <li><p>CTR - CounTeR, 计数器模式</p> <ul><li>特点: 密文没有规律,  明文分组是和一个数据流进行的按位异或操作, 最终生成了密文</li> <li>不需要初始化向量
<ul><li>go接口中的iv可以理解为随机数种子, iv的长度 == 明文分组的长度</li></ul></li> <li>不需要填充</li></ul></li> <li><p>最后一个明文分组的填充</p> <ul><li>使用cbc, ecb需要填充
<ul><li>要求:
<ul><li>明文分组中进行了填充, 然后加密</li> <li>解密密文得到明文, 需要把填充的字节删除</li></ul></li></ul></li> <li>使用 ofb, cfb, ctr不需要填充</li></ul></li> <li><p>初始化向量 - IV</p> <ul><li>ecb, ctr模式不需要初始化向量</li> <li>cbc, ofc, cfb需要初始化向量
<ul><li>初始化向量的长度
<ul><li>des/3des -&gt; 8字节</li> <li>aes -&gt; 16字节</li></ul></li> <li>加解密使用的初始化向量相同</li></ul></li></ul></li></ol> <h3 id="_1-4-对称加密在go中的实现"><a href="#_1-4-对称加密在go中的实现" class="header-anchor">#</a> 1.4 对称加密在go中的实现</h3> <ol><li><p>des</p></li> <li><p>3des</p></li> <li><p>aes</p> <div class="language-shell extra-class"><pre class="language-shell"><code><span class="token comment"># 加密流程:</span>
<span class="token number">1</span>. 创建一个底层使用des/3des/aes的密码接口
	<span class="token string">&quot;crypto/des&quot;</span>
	func NewCipher<span class="token punctuation">(</span>key <span class="token punctuation">[</span><span class="token punctuation">]</span>byte<span class="token punctuation">)</span> <span class="token punctuation">(</span>cipher.Block, error<span class="token punctuation">)</span> <span class="token comment"># -- des</span>
	func NewTripleDESCipher<span class="token punctuation">(</span>key <span class="token punctuation">[</span><span class="token punctuation">]</span>byte<span class="token punctuation">)</span> <span class="token punctuation">(</span>cipher.Block, error<span class="token punctuation">)</span>	<span class="token comment"># -- 3des</span>
	<span class="token string">&quot;crypto/aes&quot;</span>
	func NewCipher<span class="token punctuation">(</span>key <span class="token punctuation">[</span><span class="token punctuation">]</span>byte<span class="token punctuation">)</span> <span class="token punctuation">(</span>cipher.Block, error<span class="token punctuation">)</span> <span class="token comment"># == aes</span>
<span class="token number">2</span>. 如果使用的是cbc/ecb分组模式需要对明文分组进行填充
<span class="token number">3</span>. 创建一个密码分组模式的接口对象
	- cbc
	func NewCBCEncrypter<span class="token punctuation">(</span>b Block, iv <span class="token punctuation">[</span><span class="token punctuation">]</span>byte<span class="token punctuation">)</span> BlockMode <span class="token comment"># 加密</span>
	- cfb
	func NewCFBEncrypter<span class="token punctuation">(</span>block Block, iv <span class="token punctuation">[</span><span class="token punctuation">]</span>byte<span class="token punctuation">)</span> Stream <span class="token comment"># 加密</span>
	- ofb
	- ctr
<span class="token number">4</span>. 加密, 得到密文
	
</code></pre></div></li></ol> <h2 id="_02-非对称加密"><a href="#_02-非对称加密" class="header-anchor">#</a> 02 - 非对称加密</h2> <h3 id="_1-对称加密的弊端"><a href="#_1-对称加密的弊端" class="header-anchor">#</a> 1.  对称加密的弊端'</h3> <ul><li><p>秘钥分发困难</p></li> <li><p>可以通过非对称加密完成秘钥的分发</p> <blockquote><p>https</p> <p>Alice 和 Bob通信, Alice给bob发送数据, 使用对称加密的方式</p> <ol><li>生成一个非对称的秘钥对, bob生成</li> <li>bob将公钥发送给alice</li> <li>alice生成一个用于对称加密的秘钥</li> <li>alice使用bob的公钥就对称加密的秘钥进行加密, 并且发送给bob</li> <li>bob使用私钥就数据解密, 得到对称加密的秘钥</li> <li>通信的双方使用写好的秘钥进行对称加密数据加密</li></ol></blockquote></li></ul> <h3 id="_2-非对称加密的秘钥"><a href="#_2-非对称加密的秘钥" class="header-anchor">#</a> 2. 非对称加密的秘钥</h3> <ul><li>不存在秘钥分发困难的问题</li></ul> <h4 id="_2-1-场景分析"><a href="#_2-1-场景分析" class="header-anchor">#</a> 2.1 场景分析</h4> <p>数据对谁更重要, 谁就拿私钥</p> <ul><li>直观上看: 私钥比公钥长</li> <li>使用第三方工具生成密钥对: 公钥文件xxx.pub xxx</li></ul> <blockquote><ol><li><p>通信流程, 信息加密  （A写数据, 发送给B, 信息只允许B读）</p> <p>A: 公钥</p> <p>B: 私钥</p></li> <li><p>登录认证 （客户端要登录, 连接服务器, 向服务器请求个人数据）</p> <p>客户端:  私钥</p> <p>服务器:  公钥</p></li> <li><p>数字签名（表明信息没有受到伪造，确实是信息拥有者发出来的，附在信息原文的后面）</p> <ul><li>发送信息的人:   私钥</li> <li>收到信息的人:   公钥</li></ul></li> <li><p>网银U盾</p> <ul><li>个人: 私钥</li> <li>银行拿公钥</li></ul></li></ol></blockquote> <h3 id="_3-使用rsa非对称加密通信流程"><a href="#_3-使用rsa非对称加密通信流程" class="header-anchor">#</a> 3. 使用RSA非对称加密通信流程</h3> <blockquote><p>要求: Alice 给 bob发送数据, 保证数据信息只有bob能看到</p></blockquote> <h3 id="_4-生成rsa的秘钥对"><a href="#_4-生成rsa的秘钥对" class="header-anchor">#</a> 4. 生成RSA的秘钥对</h3> <h4 id="_4-1-一些概念"><a href="#_4-1-一些概念" class="header-anchor">#</a> 4.1 一些概念</h4> <ol><li>x509证书规范、pem、base64
<ul><li>pem编码规范 - 数据加密</li> <li>base64 - 对数据编码, 可逆
<ul><li>不管原始数据是什么, 将原始数据使用64个字符来替代
<ul><li>a-z  A-Z 0-9 + /</li></ul></li></ul></li></ul></li> <li>ASN.1抽象语法标记</li> <li>PKCS1标准</li></ol> <h4 id="_4-2-密钥对生成流程"><a href="#_4-2-密钥对生成流程" class="header-anchor">#</a> 4.2 密钥对生成流程</h4> <ul><li><p>生成私钥操作流程概述</p> <blockquote><ol><li><p>使用rsa中的GenerateKey方法生成私钥</p> <p>func GenerateKey(random io.Reader, bits int) (priv *PrivateKey, err error)</p> <ul><li>rand.Reader   -&gt; import &quot;crypto/rand&quot;</li> <li>1024 的整数倍 - 建议</li></ul></li> <li><p>通过x509标准将得到的ras私钥序列化为ASN.1 的 DER编码字符串</p> <p>func MarshalPKCS1PrivateKey(key *rsa.PrivateKey) []byte</p></li> <li><p>将私钥字符串设置到pem格式块中</p> <p>初始化一个pem.Block块</p> <div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">type</span> Block <span class="token keyword">struct</span> <span class="token punctuation">{</span>
    Type    <span class="token builtin">string</span>            <span class="token comment">// 得自前言的类型（如&quot;RSA PRIVATE KEY&quot;）</span>
    Headers <span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span><span class="token builtin">string</span> <span class="token comment">// 可选的头项</span>
    Bytes   <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span>            <span class="token comment">// 内容解码后的数据，一般是DER编码的ASN.1结构</span>
<span class="token punctuation">}</span>
</code></pre></div></li> <li><p>通过pem将设置好的数据进行编码, 并写入磁盘文件中</p> <p>func Encode(out io.Writer, b *Block) error</p> <ul><li>out - 准备一个文件指针</li></ul></li></ol></blockquote></li> <li><p>生成公钥操作流程</p> <blockquote><ol><li><p>从得到的私钥对象中将公钥信息取出</p> <div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">type</span> PrivateKey <span class="token keyword">struct</span> <span class="token punctuation">{</span>
    PublicKey            <span class="token comment">// 公钥</span>
    D         <span class="token operator">*</span>big<span class="token punctuation">.</span>Int   <span class="token comment">// 私有的指数</span>
    Primes    <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token operator">*</span>big<span class="token punctuation">.</span>Int <span class="token comment">// N的素因子，至少有两个</span>
    <span class="token comment">// 包含预先计算好的值，可在某些情况下加速私钥的操作</span>
    Precomputed PrecomputedValues
<span class="token punctuation">}</span>
</code></pre></div></li> <li><p>通过x509标准将得到 的rsa公钥序列化为字符串</p> <div class="language- extra-class"><pre class="language-text"><code>func MarshalPKIXPublicKey(pub interface{}) ([]byte, error)
</code></pre></div></li> <li><p>将公钥字符串设置到pem格式块中</p> <p>type Block struct {
Type    string            // 得自前言的类型（如&quot;RSA PRIVATE KEY&quot;）
Headers map[string]string // 可选的头项
Bytes   []byte            // 内容解码后的数据，一般是DER编码的ASN.1结构
}</p></li> <li><p>通过pem将设置好的数据进行编码, 并写入磁盘文件</p> <p>func Encode(out io.Writer, b *Block) error</p></li></ol></blockquote></li></ul> <h3 id="_5-rsa加解密"><a href="#_5-rsa加解密" class="header-anchor">#</a> 5. RSA加解密</h3> <h4 id="_5-1-rsa加密"><a href="#_5-1-rsa加密" class="header-anchor">#</a> 5.1 RSA加密</h4> <blockquote><ol><li><p>将公钥文件中的公钥读出, 得到使用pem编码的字符串</p> <p>-- 读文件</p></li> <li><p>将得到的字符串解码</p> <p>-- pem.Decode</p></li> <li><p>使用x509将编码之后的公钥解析出来</p> <p>-- func ParsePKCS1PrivateKey(der []byte) (key *rsa.PrivateKey, err error)</p></li> <li><p>使用得到的公钥通过rsa进行数据加密</p></li></ol></blockquote> <h4 id="_5-2-rsa解密"><a href="#_5-2-rsa解密" class="header-anchor">#</a> 5.2 RSA解密</h4> <blockquote><ol><li>将私钥文件中的私钥读出, 得到使用pem编码的字符串</li> <li>将得到的字符串解码</li> <li>使用x509将编码之后的私钥解析出来</li> <li>使用得到的私钥通过rsa进行数据解密</li></ol></blockquote> <h3 id="_6-哈希算法"><a href="#_6-哈希算法" class="header-anchor">#</a> 6. 哈希算法</h3> <h3 id="_6-1-概念"><a href="#_6-1-概念" class="header-anchor">#</a> 6.1 概念</h3> <p>称谓: 单向散列函数, 哈希函数, 杂凑函数, 消息摘要函数</p> <p>接收的输入: 原像</p> <p>输出: 散列值, 哈希值, 指纹, 摘要</p> <h3 id="_6-2-单向散列函数特性"><a href="#_6-2-单向散列函数特性" class="header-anchor">#</a> 6.2 单向散列函数特性</h3> <ol><li><p>将任意长度的数据转换成固定长度的数据</p></li> <li><p>很强的抗碰撞性</p></li> <li><p>不可逆</p></li> <li><p>MD4/MD5</p> <ul><li>不安全</li> <li>散列值长度: 128bit == 16byte</li></ul></li> <li><p>sha1</p> <ul><li>不安全</li> <li>散列值长度: 160bit == 20byte</li></ul></li> <li><p>sha2 - 安全</p> <ul><li>sha224
<ul><li>散列值长度: 224bit == 28byte</li></ul></li> <li>sha256
<ul><li>散列值长度: 256== 32byte</li></ul></li> <li>sha384
<ul><li>散列值长度: 384bit == 48byte</li></ul></li> <li>sha512
<ul><li>散列值长度: 512bit == 64byte</li></ul></li></ul> <h3 id="_6-3-go中使用单向散列函数"><a href="#_6-3-go中使用单向散列函数" class="header-anchor">#</a> 6.3 go中使用单向散列函数</h3> <div class="language-go extra-class"><pre class="language-go"><code><span class="token comment">// 第一种方式, 直接调用sum</span>
<span class="token comment">// 适用于数据量比较小的情况</span>
<span class="token keyword">func</span> <span class="token function">Sum</span><span class="token punctuation">(</span>data <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span><span class="token punctuation">)</span> <span class="token punctuation">[</span>Size<span class="token punctuation">]</span><span class="token builtin">byte</span>

<span class="token comment">// 第二种方式</span>
<span class="token comment">// 1. 创建哈希接口对象</span>
<span class="token keyword">func</span> <span class="token function">New</span><span class="token punctuation">(</span><span class="token punctuation">)</span> hash<span class="token punctuation">.</span>Hash
<span class="token keyword">type</span> Hash <span class="token keyword">interface</span> <span class="token punctuation">{</span>
    <span class="token comment">// 通过嵌入的匿名io.Writer接口的Write方法向hash中添加更多数据，永远不返回错误</span>
    io<span class="token punctuation">.</span>Writer
    <span class="token comment">// 返回添加b到当前的hash值后的新切片，不会改变底层的hash状态</span>
    <span class="token function">Sum</span><span class="token punctuation">(</span>b <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span><span class="token punctuation">)</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span>
    <span class="token comment">// 重设hash为无数据输入的状态</span>
    <span class="token function">Reset</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token comment">// 返回Sum会返回的切片的长度</span>
    <span class="token function">Size</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">int</span>
    <span class="token comment">// 返回hash底层的块大小；Write方法可以接受任何大小的数据，</span>
    <span class="token comment">// 但提供的数据是块大小的倍数时效率更高</span>
    <span class="token function">BlockSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">int</span>
<span class="token punctuation">}</span>
<span class="token keyword">type</span> Writer <span class="token keyword">interface</span> <span class="token punctuation">{</span>
    <span class="token function">Write</span><span class="token punctuation">(</span>p <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span><span class="token punctuation">)</span> <span class="token punctuation">(</span>n <span class="token builtin">int</span><span class="token punctuation">,</span> err <span class="token builtin">error</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token comment">// 2. 往创建出的哈希对象中添加数据</span>
hash<span class="token punctuation">.</span>Hash<span class="token punctuation">.</span><span class="token function">Write</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token function">byte</span><span class="token punctuation">(</span><span class="token string">&quot;添加的数据...&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
hash<span class="token punctuation">.</span>Hash<span class="token punctuation">.</span><span class="token function">Write</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token function">byte</span><span class="token punctuation">(</span><span class="token string">&quot;添加的数据...&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
hash<span class="token punctuation">.</span>Hash<span class="token punctuation">.</span><span class="token function">Write</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token function">byte</span><span class="token punctuation">(</span><span class="token string">&quot;添加的数据...&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
hash<span class="token punctuation">.</span>Hash<span class="token punctuation">.</span><span class="token function">Write</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token function">byte</span><span class="token punctuation">(</span><span class="token string">&quot;添加的数据...&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token comment">// 3. 计算结果, md5就是散列值</span>
md5 <span class="token operator">:=</span> hash<span class="token punctuation">.</span><span class="token function">Sum</span><span class="token punctuation">(</span><span class="token boolean">nil</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 散列值一般是一个二进制的字符串, 有些字符不可见, 需要格式化</span>
<span class="token comment">// 格式化为16进制的数字串 - 0-9, a-f</span>
<span class="token keyword">func</span> <span class="token function">EncodeToString</span><span class="token punctuation">(</span>src <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span><span class="token punctuation">)</span> <span class="token builtin">string</span>
<span class="token comment">// 数据转换完成之后, 长度是原来的2倍</span>

</code></pre></div><ol><li>计算一个大文件比如1G文件的散列值</li> <li>使用udp的方式分发秘钥, 进行一个对称加密的通信
<ul><li>服务器
<ul><li>生成密钥对</li> <li>公钥发送给客户端</li></ul></li> <li>客户端
<ul><li>客户端收到了公钥</li> <li>生成一个秘钥 - 用于对称加密</li> <li>使用公钥加密, 发送给服务器</li></ul></li></ul></li></ol></li></ol> <h3 id="对称加密和非对称加密总结"><a href="#对称加密和非对称加密总结" class="header-anchor">#</a> 对称加密和非对称加密总结</h3> <ol><li><p>概念</p> <ul><li><p>加密三要素</p> <ul><li>明文/密文</li> <li>秘钥</li> <li>算法</li></ul></li> <li><p>对称加密和非对称加密</p> <ul><li>对称加密: 加解密使用同一个秘钥, 1个
<ul><li>效率高</li></ul></li> <li>非...: 密钥对
<ul><li>公钥加密, 私钥解密</li> <li>私钥加密, 公钥解密</li></ul></li></ul></li> <li><p>对称加密中的公开的加密算法</p> <ul><li>des
<ul><li>分组长度: 8字节</li> <li>秘钥长度: 8字节</li></ul></li> <li>3des
<ul><li>分组长度: 8字节</li> <li>秘钥长度: 24byte</li></ul></li> <li>aes
<ul><li>分组长度: 16字节</li> <li>秘钥长度: 16字节, 24字节, 32字节
<ul><li>在go的api中只能使用16字节</li></ul></li></ul></li></ul></li> <li><p>对称加密的分组模式</p> <ul><li><p>EBC - 不推荐使用</p></li> <li><p>CBC - 常用的方式</p> <ul><li><p>准备的数据:</p> <ul><li>初始化向量iv - 字符数组</li> <li>长度 == 明文分组长度</li> <li>加解密初始化向量值必须相同</li> <li>秘钥
<ul><li>根据加密算法定</li></ul></li></ul></li></ul> <p>===========================</p></li> <li><p>OFB - 不推荐使用</p></li> <li><p>CFB - 不推荐使用</p></li> <li><p>CTR - 推荐使用, 效率最高</p></li></ul></li></ul></li></ol> <h2 id="_03-消息认证码"><a href="#_03-消息认证码" class="header-anchor">#</a> 03 - 消息认证码</h2> <h3 id="_1-1-消息认证"><a href="#_1-1-消息认证" class="header-anchor">#</a> 1.1 消息认证</h3> <blockquote><p><strong>消息认证码（message authentication code）是一种确认完整性并进行认证的技术，取三个单词的首字母，简称为MAC。</strong></p></blockquote> <p><img src="http://static.zhequtao.com/study/04mimaxue/day03/1539176665517.png" alt="1539176665517"></p> <ul><li><p>思考改进方案?</p> <p>从哈希函数入手</p> <p>需要将要发送的数据进行哈希运算, 将哈希值和原始数据一并发送</p> <p>需要在进行哈希运算的时候引入加密的步骤</p> <ul><li>在alice对数据进行哈希运算的时候引入一个秘钥, 让其参与哈希运算, 生成散列值</li> <li>bob对数据校验
<ul><li>bob收到原始和散列值之后,
<ul><li>处理原始数据: 通过秘钥和哈希算法对原始数据生成散列值</li> <li>散列值比较: 生成的散列值 和  接收到的散列值进行比对</li></ul></li></ul></li></ul></li></ul> <h3 id="_1-2-消息认证码的使用步骤"><a href="#_1-2-消息认证码的使用步骤" class="header-anchor">#</a> 1.2 消息认证码的使用步骤</h3> <p><img src="http://static.zhequtao.com/study/04mimaxue/day03/1539177690828.png" alt="1539177690828"></p> <blockquote><ol><li>前提条件:
<ul><li>在消息认证码生成的一方和校验的一方, 必须有一个秘钥</li> <li>双方约定好使用同样的哈希函数对数据进行运算</li></ul></li> <li>流程:
<ul><li>发送者:
<ul><li>发送原始法消息</li> <li>将原始消息生成消息认证码
<ul><li>((原始消息) + 秘钥)  *   函数函数 = 散列值(消息认证码)</li></ul></li> <li>将消息认证码发送给对方</li></ul></li> <li>接收者:
<ul><li>接收原始数据</li> <li>接收消息认证码</li> <li>校验:
<ul><li>( 接收的消息  +  秘钥 ) * 哈希函数   = 新的散列值</li> <li>通过新的散列值和接收的散列值进行比较</li></ul></li></ul></li></ul></li></ol></blockquote> <h3 id="_1-3-go中对消息认证码的使用"><a href="#_1-3-go中对消息认证码的使用" class="header-anchor">#</a> 1.3 go中对消息认证码的使用</h3> <blockquote><p>有一个包: crypto/hmac</p> <div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">New</span><span class="token punctuation">(</span>h <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> hash<span class="token punctuation">.</span>Hash<span class="token punctuation">,</span> key <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span><span class="token punctuation">)</span> hash<span class="token punctuation">.</span>Hash
<span class="token operator">-</span> 返回值<span class="token punctuation">:</span> hash接口
<span class="token operator">-</span> 参数<span class="token number">1</span><span class="token punctuation">:</span> 函数函数的函数名
	sha1<span class="token punctuation">.</span><span class="token builtin">new</span>
	md5<span class="token punctuation">.</span><span class="token builtin">new</span>
	sha256<span class="token punctuation">.</span><span class="token builtin">new</span>
<span class="token operator">-</span> 参数<span class="token number">2</span><span class="token punctuation">:</span> 秘钥

第二步<span class="token punctuation">:</span> 添加数据
<span class="token keyword">type</span> Hash <span class="token keyword">interface</span> <span class="token punctuation">{</span>
    <span class="token comment">// 通过嵌入的匿名io.Writer接口的Write方法向hash中添加更多数据，永远不返回错误</span>
    io<span class="token punctuation">.</span>Writer
    <span class="token comment">// 返回添加b到当前的hash值后的新切片，不会改变底层的hash状态</span>
    <span class="token function">Sum</span><span class="token punctuation">(</span>b <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span><span class="token punctuation">)</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span>
    <span class="token comment">// 重设hash为无数据输入的状态</span>
    <span class="token function">Reset</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token comment">// 返回Sum会返回的切片的长度</span>
    <span class="token function">Size</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">int</span>
    <span class="token comment">// 返回hash底层的块大小；Write方法可以接受任何大小的数据，</span>
    <span class="token comment">// 但提供的数据是块大小的倍数时效率更高</span>
    <span class="token function">BlockSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">int</span>
<span class="token punctuation">}</span>
<span class="token keyword">type</span> Writer <span class="token keyword">interface</span> <span class="token punctuation">{</span>
    <span class="token function">Write</span><span class="token punctuation">(</span>p <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span><span class="token punctuation">)</span> <span class="token punctuation">(</span>n <span class="token builtin">int</span><span class="token punctuation">,</span> err <span class="token builtin">error</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
第三步<span class="token punctuation">:</span> 计算散列值
</code></pre></div></blockquote> <h3 id="_1-4-消息认证码的问题"><a href="#_1-4-消息认证码的问题" class="header-anchor">#</a> 1.4 消息认证码的问题</h3> <ol><li>弊端
<ul><li>有秘钥分发困难的问题</li></ul></li> <li>无法解决的问题
<ul><li>不能进行第三方证明</li> <li>不能防止否认</li></ul></li></ol> <h2 id="_04-数字签名"><a href="#_04-数字签名" class="header-anchor">#</a> 04 - 数字签名</h2> <h3 id="_2-1-签名的生成和验证"><a href="#_2-1-签名的生成和验证" class="header-anchor">#</a> 2.1 签名的生成和验证</h3> <blockquote><ol><li>签名
<ul><li>有原始数据对其进行哈希运算   -&gt;   散列值</li> <li>使用非对称加密的<font color="red">私钥</font>对散列值加密 -&gt; 签名</li> <li>将原始数据和签名一并发送给对方</li></ul></li> <li>验证
<ul><li>接收数据
<ul><li>原始数据</li> <li>数字签名</li></ul></li> <li>数字签名, 需要使用<font color="red">公钥</font>解密, 得到散列值</li> <li>对原始数据进行哈希运算得到新的散列值</li></ul></li></ol></blockquote> <h3 id="_2-2-非对称加密和数字签名"><a href="#_2-2-非对称加密和数字签名" class="header-anchor">#</a> 2.2 非对称加密和数字签名</h3> <blockquote><p>总结:</p> <ol><li>数据通信
<ul><li>公钥加密, 私钥解密</li></ul></li> <li>数字签名:</li></ol> <div class="language- extra-class"><pre><code>- 私钥加密, 公钥解密
</code></pre></div></blockquote> <h3 id="_2-3-数字签名的方法"><a href="#_2-3-数字签名的方法" class="header-anchor">#</a> 2.3 数字签名的方法</h3> <p><img src="http://static.zhequtao.com/study/04mimaxue/day03/1539177860475.png" alt="1539177860475"></p> <h3 id="_2-4-使用rsa进行数字签名"><a href="#_2-4-使用rsa进行数字签名" class="header-anchor">#</a> 2.4 使用RSA进行数字签名</h3> <ol><li><p>使用rsa生成密钥对</p> <blockquote><ol><li>生成密钥对</li> <li>序列化</li> <li>保存到磁盘文件</li></ol></blockquote></li> <li><p>使用私钥进行数字签名</p> <blockquote><ol><li><p>打开磁盘的私钥文件</p></li> <li><p>将私钥文件中的内容读出</p></li> <li><p>使用pem对数据解码, 得到了pem.Block结构体变量</p></li> <li><p>x509将数据解析成私钥结构体 -&gt; 得到了私钥</p></li> <li><p>创建一个哈希对象 -&gt; md5/sha1</p></li> <li><p>给哈希对象添加数据</p></li> <li><p>计算哈希值</p></li> <li><p>使用rsa中的函数对散列值签名</p> <div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">SignPKCS1v15</span><span class="token punctuation">(</span>rand io<span class="token punctuation">.</span>Reader<span class="token punctuation">,</span> priv <span class="token operator">*</span>PrivateKey<span class="token punctuation">,</span> hash crypto<span class="token punctuation">.</span>Hash<span class="token punctuation">,</span> hashed <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span><span class="token punctuation">)</span> <span class="token punctuation">(</span>s <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span><span class="token punctuation">,</span> err <span class="token builtin">error</span><span class="token punctuation">)</span>
参数<span class="token number">1</span><span class="token punctuation">:</span> rand<span class="token punctuation">.</span>Reader
参数<span class="token number">2</span><span class="token punctuation">:</span> 非对称加密的私钥
参数<span class="token number">3</span><span class="token punctuation">:</span> 使用的哈希算法
	crypto<span class="token punctuation">.</span>sha1
	crypto<span class="token punctuation">.</span>md5
参数<span class="token number">4</span><span class="token punctuation">:</span> 数据计算之后得到的散列值
返回值<span class="token punctuation">:</span> 
<span class="token operator">-</span> s<span class="token punctuation">:</span> 得到的签名数据
<span class="token operator">-</span> err<span class="token punctuation">:</span> 错误信息
</code></pre></div></li></ol></blockquote></li> <li><p>使用公钥进行签名认证</p> <blockquote><ol><li><p>打开公钥文件, 将文件内容读出 - []byte</p></li> <li><p>使用pem解码 -&gt; 得到pem.Block结构体变量</p></li> <li><p>使用x509对pem.Block中的Bytes变量中的数据进行解析 -&gt;  得到一接口</p></li> <li><p>进行类型断言 -&gt; 得到了公钥结构体</p></li> <li><p>对原始消息进行哈希运算(和签名使用的哈希算法一致) -&gt; 散列值</p> <ol><li>创建哈希接口</li> <li>添加数据</li> <li>哈希运算</li></ol></li> <li><p>签名认证 - rsa中的函数</p> <div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">VerifyPKCS1v15</span><span class="token punctuation">(</span>pub <span class="token operator">*</span>PublicKey<span class="token punctuation">,</span> hash crypto<span class="token punctuation">.</span>Hash<span class="token punctuation">,</span> hashed <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span><span class="token punctuation">,</span> sig <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span><span class="token punctuation">)</span> <span class="token punctuation">(</span>err <span class="token builtin">error</span><span class="token punctuation">)</span>
参数<span class="token number">1</span><span class="token punctuation">:</span> 公钥
参数<span class="token number">2</span><span class="token punctuation">:</span> 哈希算法 <span class="token operator">-</span><span class="token operator">&gt;</span> 与签名使用的哈希算法一致
参数<span class="token number">3</span><span class="token punctuation">:</span> 将原始数据进行哈希原始得到的散列值
参数<span class="token number">4</span><span class="token punctuation">:</span> 签名的字符串
返回值<span class="token punctuation">:</span> 
	<span class="token operator">-</span> <span class="token boolean">nil</span> <span class="token operator">-</span><span class="token operator">&gt;</span> 验证成功
	<span class="token operator">-</span> <span class="token operator">!=</span><span class="token boolean">nil</span> <span class="token operator">-</span><span class="token operator">&gt;</span> 失败
</code></pre></div></li></ol></blockquote></li></ol> <h3 id="_2-5-使用椭圆曲线进行数字签名"><a href="#_2-5-使用椭圆曲线进行数字签名" class="header-anchor">#</a> 2.5 使用椭圆曲线进行数字签名</h3> <blockquote><p>椭圆曲线在go中对应的包: import &quot;crypto/elliptic&quot;</p> <p>使用椭圆曲线在go中进行数字签名: import &quot;crypto/ecdsa&quot;</p> <p>美国FIPS186-2标准, 推荐使用5个素域上的椭圆曲线, 这5个素数模分别是:</p> <p>P~192~ = 2^192^ - 2^64^ - 1</p> <p>P~224~ = 2^224^ - 2^96^ + 1</p> <p>P~256~ = 2^256^ - 2^224^  + 2^192^ - 2^96^ -1</p> <p>P~384~ = 2^384^ - 2^128^  - 2^96^ + 2^32^ -1</p> <p>P~512~ = 2^512^ - 1</p></blockquote> <ol><li><p>秘钥对称的生成, 并保存到磁盘</p> <blockquote><ol><li><p>使用ecdsa生成密钥对</p> <div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">GenerateKey</span><span class="token punctuation">(</span>c elliptic<span class="token punctuation">.</span>Curve<span class="token punctuation">,</span> rand io<span class="token punctuation">.</span>Reader<span class="token punctuation">)</span> <span class="token punctuation">(</span>priv <span class="token operator">*</span>PrivateKey<span class="token punctuation">,</span> err <span class="token builtin">error</span><span class="token punctuation">)</span>
</code></pre></div></li> <li><p>将私钥写入磁盘</p> <ul><li><p>使用x509进行序列化</p> <div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">MarshalECPrivateKey</span><span class="token punctuation">(</span>key <span class="token operator">*</span>ecdsa<span class="token punctuation">.</span>PrivateKey<span class="token punctuation">)</span> <span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span><span class="token punctuation">,</span> <span class="token builtin">error</span><span class="token punctuation">)</span>
</code></pre></div></li> <li><p>将得到的切片字符串放入pem.Block结构体中</p> <p>block := pem.Block{</p> <p>Type : &quot;描述....&quot;,</p> <p>Bytes : MarshalECPrivateKey返回值中的切片字符串,</p> <p>}</p></li> <li><p>使用pem编码</p> <p>pem.Encode();</p></li></ul></li> <li><p>将公钥写入磁盘</p> <ul><li><p>从私钥中得到公钥</p></li> <li><p>使用x509进行序列化</p> <div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">MarshalPKIXPublicKey</span><span class="token punctuation">(</span>pub <span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span><span class="token punctuation">,</span> <span class="token builtin">error</span><span class="token punctuation">)</span>
</code></pre></div></li> <li><p>将得到的切片字符串放入pem.Block结构体中</p> <p>block := pem.Block{</p> <p>Type : &quot;描述....&quot;,</p> <p>Bytes : MarshalECPrivateKey返回值中的切片字符串,</p> <p>}</p></li> <li><p>使用pem编码</p> <p>pem.Encode();</p></li></ul></li></ol></blockquote></li> <li><p>使用私钥进行数字签名</p> <blockquote><ol><li><p>打开私钥文件, 将内容读出来 -&gt;[]byte</p></li> <li><p>使用pem进行数据解码 -&gt; pem.Decode()</p></li> <li><p>使用x509, 对私钥进行还原</p> <div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">ParseECPrivateKey</span><span class="token punctuation">(</span>der <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span><span class="token punctuation">)</span> <span class="token punctuation">(</span>key <span class="token operator">*</span>ecdsa<span class="token punctuation">.</span>PrivateKey<span class="token punctuation">,</span> err <span class="token builtin">error</span><span class="token punctuation">)</span>
</code></pre></div></li> <li><p>对原始数据进行哈希运算 -&gt; 散列值</p></li> <li><p>进行数字签名</p> <div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">Sign</span><span class="token punctuation">(</span>rand io<span class="token punctuation">.</span>Reader<span class="token punctuation">,</span> priv <span class="token operator">*</span>PrivateKey<span class="token punctuation">,</span> hash <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span><span class="token punctuation">)</span> <span class="token punctuation">(</span>r<span class="token punctuation">,</span> s <span class="token operator">*</span>big<span class="token punctuation">.</span>Int<span class="token punctuation">,</span> err <span class="token builtin">error</span><span class="token punctuation">)</span>
<span class="token operator">-</span> 得到的r和s不能直接使用<span class="token punctuation">,</span> 因为这是指针
	应该将这两块内存中的数据进行序列化 <span class="token operator">-</span><span class="token operator">&gt;</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span>
	<span class="token keyword">func</span> <span class="token punctuation">(</span>z <span class="token operator">*</span>Int<span class="token punctuation">)</span> <span class="token function">MarshalText</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">(</span>text <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span><span class="token punctuation">,</span> err <span class="token builtin">error</span><span class="token punctuation">)</span>
</code></pre></div></li></ol></blockquote></li> <li><p>使用公钥验证数字签名</p> <blockquote><ol><li><p>打开公钥文件, 将里边的内容读出 -&gt; []byte</p></li> <li><p>pem解码 -&gt; pem.Decode()</p></li> <li><p>使用x509对公钥还原</p> <div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">ParsePKIXPublicKey</span><span class="token punctuation">(</span>derBytes <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span><span class="token punctuation">)</span> <span class="token punctuation">(</span>pub <span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> err <span class="token builtin">error</span><span class="token punctuation">)</span>
</code></pre></div></li> <li><p>将接口 -&gt; 公钥</p></li> <li><p>对原始数据进行哈希运算 -&gt; 得到散列值</p></li> <li><p>签名的认证 - &gt; ecdsa</p> <div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">Verify</span><span class="token punctuation">(</span>pub <span class="token operator">*</span>PublicKey<span class="token punctuation">,</span> hash <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span><span class="token punctuation">,</span> r<span class="token punctuation">,</span> s <span class="token operator">*</span>big<span class="token punctuation">.</span>Int<span class="token punctuation">)</span> <span class="token builtin">bool</span>
<span class="token operator">-</span> 参数<span class="token number">1</span><span class="token punctuation">:</span> 公钥
<span class="token operator">-</span> 参数<span class="token number">2</span><span class="token punctuation">:</span> 原始数据生成的散列值
<span class="token operator">-</span> 参数<span class="token number">3</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">:</span> 通过签名得到的连个点
	<span class="token keyword">func</span> <span class="token punctuation">(</span>z <span class="token operator">*</span>Int<span class="token punctuation">)</span> <span class="token function">UnmarshalText</span><span class="token punctuation">(</span>text <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span><span class="token punctuation">)</span> <span class="token builtin">error</span>
</code></pre></div></li></ol></blockquote></li></ol> <h3 id="_2-6-数字签名无法解决的问题"><a href="#_2-6-数字签名无法解决的问题" class="header-anchor">#</a> 2.6 数字签名无法解决的问题</h3> <p><img src="http://static.zhequtao.com/study/04mimaxue/day03/1539178819165.png" alt="1539178819165"></p> <h2 id="_05-证书"><a href="#_05-证书" class="header-anchor">#</a> 05 - 证书</h2> <blockquote><p>公钥证书（Public-Key Certificate，PKC)其实和驾照很相似，里面记有姓名、组织、邮箱地址等<font color="red">个人信息</font>，以及属于<font color="red">此人的公钥, 并由认证机构（Certification Authority、Certifying Authority, CA）施加数字签名</font>。只要看到公钥证书，我们就可以知道认证机构认定该公钥的确属于此人。公钥证书也简称为证书（certificate）。</p></blockquote> <h3 id="_1-1-证书的应用场景"><a href="#_1-1-证书的应用场景" class="header-anchor">#</a> 1.1 证书的应用场景</h3> <p><img src="http://static.zhequtao.com/study/04mimaxue/day04/1539265302304.png" alt="1539265302304"></p> <blockquote><ol><li><font color="red" size="4">Bob生成密钥对</font> <ul><li>可以将bob看成百度, 提供是web服务器</li> <li>生成一个密钥对
<ul><li>公钥  -&gt; 分发</li> <li>私钥 -&gt; 百度留着</li></ul></li></ul></li> <li><font color="red" size="4">Bob在认证机构Trent注册自己的公钥</font></li> <li><ul><li>百度找了一大家都信赖的机构, 来证明这个公钥是百度的</li> <li>认证机构会生成一个证书, 写明了公钥属于百度
<ul><li>认证机构也有一个非对称加密的密钥对</li> <li>认证机构使用自己的私钥对百度的公钥进行签名, 生成了证书</li> <li>认证机构将证书发送给百度</li></ul></li></ul></li> <li><font color="red" size="4">认证机构Trent用自己的私钥对Bob的公钥施加数字签名并生成证书</font></li> <li><font color="red" size="4">Alice得到带有认证机构Trent的数字签名的Bob的公钥（证书）</font> <ul><li>alice可以看做一个客户 -&gt; 浏览器</li> <li>客户端访问的百度 -&gt; 得到了百度的证书
<ul><li>证书中有百度的公钥</li></ul></li> <li>客户端需要使用认证机构的公钥对证书进行验证
<ul><li>客户端怎么会有认证机构的公钥
<ul><li>window会预装, 或者用户自己安装</li></ul></li></ul></li></ul></li> <li><font color="red" size="4">Alice使用认证机构Trent的公钥验证数字签名，确认Bob的公钥的合法性</font> <ul><li>使用认证机构的公钥解除百度证书中签名的数据
<ul><li>百度的公钥</li> <li>百度的域名</li> <li>百度证书的有效期</li></ul></li></ul></li> <li><font color="red" size="4">Alice用Bob的公钥加密消息并发送给Bob</font> <ul><li>非对称加密</li> <li>使用公钥加密 -&gt; 对称加密秘钥分发</li></ul></li> <li><font color="red" size="4">Bob用自己的私钥解密密文得到Alice的消息</font> <ul><li>服务器使用私钥解密 -&gt; 得到对称加密的秘钥</li></ul></li></ol></blockquote> <h3 id="_1-2-证书规范和格式-x509"><a href="#_1-2-证书规范和格式-x509" class="header-anchor">#</a> 1.2 证书规范和格式 -- x509</h3> <blockquote><p><strong>X.509</strong>是一种非常通用的证书格式。所有的证书都符合ITU-T X.509国际标准，因此(理论上)为一种应用创建的证书可以用于任何其他符合X.509标准的应用。X.509证书的结构是用ASN1(Abstract Syntax Notation One)进行描述数据结构，并使用ASN.1语法进行编码。</p> <p>X.509规范中一般推荐使用PEM(Privacy Enhanced Mail）格式来存储证书相关的文件。</p> <ul><li>证书文件的文件名后缀一般为 .crt 或 .cer</li> <li>对应私钥文件的文件名后缀一般为 .key</li> <li>证书请求文件的文件名后綴为 .csr</li> <li>有时候也统一用pem作为文件名后缀。</li></ul></blockquote> <h3 id="_1-3-ca证书"><a href="#_1-3-ca证书" class="header-anchor">#</a> 1.3  CA证书</h3> <blockquote><p>CA证书顾名思义就是由CA（Certification Authority）机构发布的数字证书。要对CA证书完全理解及其作用，首先要理解SSL。SSL（security sockets layer，安全套接层）是为网络通信提供安全及数据完整性的一种安全协议。SSL3.0版本以后又被称为TLS。SSL位于TCP与各应用层之间，是操作系统向外提供的API。SSL如何保证网络通信的安全和数据的完整性呢？就是采用了两种手段：身份认证和数据加密。首先身份认证就需要用到CA证书了。</p></blockquote> <ol><li><p>证书的获取和身份的认证</p> <blockquote><p>客户端与服务端需要经过一个握手的过程才能完成身份认证，建立一个安全的连接。握手的过程如下：</p> <ol><li><p>客户端访问服务器（比如：<a href="https://www.12306.cn/" target="_blank" rel="noopener noreferrer">https://www.12306.cn<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>）,发送ssl版本、客户端支持的加密算法等消息。</p></li> <li><p>服务器向客户端发送ssl版本、加密算法、证书（证书出现了）等消息。</p></li> <li><p>客户端收到消息后，判断证书是否可信, 若可信，则继续通信，发送消息：</p> <p><font color="red">客户端生成一个随机数，从证书中获取服务器端的公钥，对随机数加密；</font></p> <p>随后信息都将使用双方协定的加密方法和密钥发送, 客户端握手结束。</p></li> <li><p>服务器端对数据解密得到随机数, 使用协商好的加密算法和秘钥进行通信</p></li></ol></blockquote></li> <li><p>客户端如何验证CA证书是可信任的?</p> <blockquote><ol><li><p>查看证书的方式:</p> <p>Internet选项 -&gt; 内容 -&gt; 证书, 打开证书窗口查看已经安装的证书</p> <p>只要电脑上安装了该证书, 就说明该证书是受信任的。使用https协议访问时，服务器发送证书向浏览器时，首先查找该证书是否已在信任列表中，然后对证书进行校验，校验成功，那么就证明证书是可信的。</p> <p>下图中<code>受信任的根证书颁发机构</code>下的证书都是根证书。</p> <p>证书验证的机制是只要根证书是受信任的，那么它的子证书都是可信的。比如说，我们使用https协议访问了需要百度证书的网站，即使我们不安装百度证书，那么网站也不会提示证书不安全，因为，生成百度证书的根证书<code>Globalsign Root CA - R1</code>证书，在受信任的证书列表中。如果一个证书的根证书是不可信的，那么这个证书肯定也是不可信任的。</p> <p>由以上可知，根证书在证书验证中极其重要，而且，根证书是无条件信任的，只要我们将根证书安装上，就说明我们对根证书是信任的。比如我们安装12306的根证书，是出于我们对国家的信任，对网站的信任，我们才放心安装这个根证书。对于一些不安全的网站的证书，一定要慎重安装。</p> <p>另外需要知道的是，【<code>受信任的根证书颁发机构</code>】中的证书是windows预先安装的一些证书，都是国际上很有权威的证书机构，他们证书的生成都有很严格的流程，因此他们的证书被认为是安全，就像我们相信银行是安全，所以把钱存入到银行。</p></li></ol></blockquote> <p><img src="http://static.zhequtao.com/study/04mimaxue/day04/1539272408707.png" alt="1539272408707"></p> <blockquote><ol start="2"><li><p>证书的颁发机构 -&gt; CA</p> <ul><li>发布根证书</li> <li>中间证书</li> <li>个人</li></ul></li> <li><p>证书的信任链 -&gt; 证书签发机构的信任链</p> <p>A是一个可信赖证书签发机构, A信任B, B就有资格去签发证书</p> <p>从等级上A比B高一级</p></li></ol></blockquote></li> <li><p>有哪些CA机构?</p> <blockquote><p>世界上较早的数字认证中心是美国的verisign<code>威瑞信</code>公司，在windows的证书窗口中可以看到好多verisign公司生成的证书, 美国的<em>DigiCert</em></p> <p>另外还有加拿大的ENTRUST公司，也是很著名的证书机构。</p> <p>中国的安全认证体系分为金融CA和非金融CA。</p> <ul><li>在金融CA方面，根证书由中国人民银行管理，</li> <li>非金融CA方面，由中国电信负责。
<ul><li>行业性CA
<ul><li>中国金融认证中心</li> <li>中国电信认证中心</li></ul></li> <li>区域性CA, 区域性CA主要是以政府为背景，以企业机制运行
<ul><li>广东CA中心</li> <li>上海CA中心</li></ul></li></ul></li></ul> <p>沃通 -- www.wosign.com/products/ssl.htm</p></blockquote></li></ol> <h3 id="_1-4-公钥基础设施-pki"><a href="#_1-4-公钥基础设施-pki" class="header-anchor">#</a> 1.4 公钥基础设施 - PKI</h3> <ol><li>PKI组成的要素
<ul><li>用户
<ul><li>申请证书的人 -&gt; web服务器端
<ul><li>申请证书
<ul><li>生成密钥对 , 或者委托ca生成</li> <li>将公钥发送给CA</li> <li>ca使用自己的私钥对得到公钥签名</li> <li>将证书发送给用户</li></ul></li> <li>发送证书
<ul><li>当客户端访问服务器的时候发送证书给客户端</li></ul></li> <li>注销证书
<ul><li>当发现私钥泄露之后</li></ul></li></ul></li> <li>使用证书的人 -&gt; 客户端
<ul><li>接收证书</li> <li>验证对方的身份信息</li></ul></li></ul></li> <li>CA认证机构
<ul><li>可以生产密钥对(可选)</li> <li>对公钥签名</li> <li>吊销证书</li></ul></li> <li>仓库
<ul><li>存储证书 -&gt; 公钥</li></ul></li></ul></li></ol> <h3 id="_2-ssl-tls"><a href="#_2-ssl-tls" class="header-anchor">#</a> 2. SSL/TLS</h3> <p><img src="http://static.zhequtao.com/study/04mimaxue/day04/1539271432019.png" alt=""></p> <blockquote><ul><li><strong>SSL</strong>：（Secure Socket Layer，安全套接字层），为Netscape所研发，用以保障在Internet上数据传输之安全，利用数据加密(Encryption)技术，可确保数据在网络上之传输过程中不会被截取。当前版本为3.0。它已被广泛地用于Web浏览器与服务器之间的身份认证和加密数据传输。
SSL协议位于TCP/IP协议与各种应用层协议之间，为数据通讯提供安全支持。SSL协议可分为两层： SSL记录协议（SSL Record Protocol）：它建立在可靠的传输协议（如TCP）之上，为高层协议提供数据封装、压缩、加密等基本功能的支持。 SSL握手协议（SSL Handshake Protocol）：它建立在SSL记录协议之上，用于在实际的数据传输开始前，通讯双方进行身份认证、协商加密算法、交换加密密钥等。</li> <li><strong>TLS</strong>：(Transport Layer Security，传输层安全协议)，用于两个应用程序之间提供保密性和数据完整性。
TLS 1.0是IETF（Internet Engineering Task Force，Internet工程任务组）制定的一种新的协议，它建立在SSL 3.0协议规范之上，是SSL 3.0的后续版本，可以理解为SSL 3.1，它是写入了 <a href="http://tools.ietf.org/html/rfc5246" target="_blank" rel="noopener noreferrer">RFC<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a> 的。该协议由两层组成： TLS 记录协议（TLS Record）和 TLS 握手协议（TLS Handshake）。较低的层为 TLS 记录协议，位于某个可靠的传输协议（例如 TCP）上面。</li></ul> <p>SSL/TLS协议提供的服务主要有：</p> <ol><li>认证用户和服务器，确保数据发送到正确的客户机和服务器；</li> <li>加密数据以防止数据中途被窃取；</li> <li>维护数据的完整性，确保数据在传输过程中不被改变。</li></ol></blockquote> <p><img src="http://static.zhequtao.com/study/04mimaxue/day04/tls-ssl.svg" alt=""></p> <ol><li><p>描述的是客户端和服务器刚建立连接之后做的事情</p> <p>第一次</p> <ul><li>客户端连接服务器
<ul><li>客户端使用的ssl版本, 客户端支持的加密算法</li></ul></li> <li>服务器
<ul><li>先将自己支持ssl版本和客户端的支持的版本比较
<ul><li>支持的不一样, 连接断开</li> <li>支持的一样, 继续</li></ul></li> <li>根据得到的客户端支持 的加密算法, 找一个服务器端也同样支持算法, 发送给客户端</li> <li>需要发送服务器的证书给客户端</li></ul></li></ul> <p>第二次:</p> <p>客户端:</p> <ul><li>接收服务器的证书</li> <li>校验证书的信息
<ul><li>校验证书的签发机构</li> <li>证书的有效期</li> <li>证书中支持 的域名和访问的域名是否一致</li></ul></li> <li>校验有问题, 浏览器会给提示</li></ul></li></ol> <h3 id="_3-https-单向认证"><a href="#_3-https-单向认证" class="header-anchor">#</a> 3. https -&gt; 单向认证</h3> <p><img src="http://static.zhequtao.com/study/04mimaxue/day04/https1.png" alt=""></p> <ol><li>服务器要准备的
<ul><li>生成密钥对</li> <li>将公钥发送给ca, 由ca签发证书</li> <li>将ca签发的证书和非对称加密的私钥部署到当前的web服务器</li></ul></li> <li>通信流程
<ol><li>客户端连接服务器, 通过一个域名
<ul><li>域名和IP地址的关系
<ul><li>域名要绑定IP地址
<ul><li>一个域名只能绑定一个IP地址</li></ul></li> <li>IP地址需要被域名绑定
<ul><li>一个IP地址可以被多个域名绑定</li></ul></li></ul></li> <li>客户端访问的域名会别解析成IP地址, 通过IP地址访问web服务器</li></ul></li> <li>服务器收到了客户端的请求
<ul><li>服务器将CA签发的证书发送给浏览器(客户端)</li></ul></li> <li>客户端拿到了服务器的公钥证书
<ul><li>读这个公钥 证书
<ul><li>验证域名</li> <li>有效期</li> <li>ca签发机构</li> <li>服务器的公钥</li></ul></li></ul></li> <li>客户会生成一个随机数 (作为对称加密的秘钥来使用的)
<ul><li>使用服务器的公钥就这个随机数进行加密</li> <li>将这个加密之后 秘钥发送给服务器</li></ul></li> <li>服务器对收到的密文解密
<ul><li>使用服务器的是要解密, 得到对称加密的秘钥</li></ul></li> <li>数据的传输
<ul><li>使用对称加密的方式对数据进行加密</li></ul></li></ol></li></ol> <h3 id="_4-自签名证书"><a href="#_4-自签名证书" class="header-anchor">#</a> 4. 自签名证书</h3> <ol><li><p>使用openssl生成自签名证书</p> <ol><li><p>创建一个目录如Mytest, 进入该目录, 在该目录下打开命令行窗口</p></li> <li><p>启动openssl</p> <div class="language-shell extra-class"><pre class="language-shell"><code>openssl    <span class="token comment"># 执行该命令即可</span>
</code></pre></div></li> <li><p>使用openssl工具生成一个RSA私钥, 注意：生成私钥，需要提供一个至少4位的密码。</p> <div class="language-shell extra-class"><pre class="language-shell"><code>genrsa -des3 -out server.key <span class="token number">2048</span>
	- des3: 使用3des对私钥进行加密
</code></pre></div></li> <li><p>生成CSR（证书签名请求）</p> <div class="language-shell extra-class"><pre class="language-shell"><code>req -new -key server.key -out server.csr
</code></pre></div></li> <li><p>删除私钥中的密码, 第一步给私钥文件设置密码是必须要做的, 如果不想要可以删掉</p> <div class="language-shell extra-class"><pre class="language-shell"><code>rsa -in server.key -out server.key
	-out 参数后的文件名可以随意起
</code></pre></div></li> <li><p>生成自签名证书</p> <div class="language-shell extra-class"><pre class="language-shell"><code>x509 -req -days <span class="token number">365</span> -in server.csr -signkey server.key -out server.crt
</code></pre></div></li></ol> <h3 id="证书总结"><a href="#证书总结" class="header-anchor">#</a> 证书总结</h3> <ol><li><p>消息认证码</p> <ul><li>是什么?
<ul><li>散列值</li></ul></li> <li>能干什么?
<ul><li>保证数据的完整性, 一致性</li></ul></li> <li>怎么生成?
<ul><li>准备的条件:  Hmac
<ul><li>原始数据</li> <li>共享秘钥 -&gt; 认证的另一方需要有同样的秘钥</li> <li>哈希算法</li></ul></li></ul></li> <li>弊端:
<ul><li>秘钥分发困难
<ul><li>使用非对称加密</li></ul></li> <li>不能第三方认证</li> <li>不能防止否认</li></ul></li></ul></li> <li><p>数字签名</p> <ul><li><p>是什么?</p> <ul><li>签名
<ul><li>签名的人生成非对称加密的密钥对</li> <li>签名的人将公钥进行分发</li> <li>签名的人将原始数据进行哈希运算 -&gt; 散列值</li> <li>签名的人使用自己的私钥对散列值进行非对称加密 -&gt; 最终得到的数据就是签名</li></ul></li> <li>校验:
<ul><li>接收签名人的公钥</li> <li>接收签名人发送的数据和签名数据</li> <li>对原始数据进行哈希运算 -&gt; 散列值</li> <li>使用公钥对签名数据解密</li> <li>将解密出的数据和散列值进行比较
<ul><li>相等 == 成功</li> <li>不..  == 失败</li></ul></li></ul></li></ul></li> <li><p>干什么?</p> <ul><li>保证数据的一致性</li> <li>进行第三方认证</li> <li>可以防止否认</li></ul></li> <li><p>能解决消息认证的弊端吗?</p> <ul><li>可以</li></ul></li> <li><p>怎么进行签名</p> <ul><li><p>RSA</p></li> <li><p>椭圆曲线签名 -&gt; ecdsa</p> <blockquote><ol><li>生成密钥对, 保存到文件中</li> <li>对公钥进行分发</li> <li>签名的人
<ul><li>将私钥从磁盘读出</li> <li>pem解码</li> <li>x509解码 -&gt; 私钥结构体</li> <li>对原始数据进行哈希运算 -&gt; 散列值</li> <li>签名</li></ul></li> <li>验证签名的人
<ul><li>将公钥从磁盘读出</li> <li>pem解码</li> <li>x509解码 -&gt; 公钥</li> <li>生成原始数据的散列值</li> <li>签名认证</li></ul></li></ol></blockquote></li></ul> <p>数字签名的缺陷?</p> <ul><li>验证签名的一方没有办法判断得到的公钥到底属于谁</li></ul></li></ul></li></ol></li></ol></div> <footer class="page-edit"><!----> <div class="last-updated"><span class="prefix">上次更新:</span> <span class="time">7/20/2020, 2:09:44 AM</span></div></footer> <div class="page-nav"><p class="inner"><span class="prev">
      ←
      <a href="/go-block/blockchain/encryption-expand.html" class="prev">常见的密码技术</a></span> <span class="next"><a href="/go-block/blockchain/ethereum.html">以太坊智能合约</a>
      →
    </span></p></div> </main></div><div class="global-ui"></div></div>
    <script src="/assets/js/app.cb35c8f6.js" defer></script><script src="/assets/js/2.063846a6.js" defer></script><script src="/assets/js/4.1ffb4609.js" defer></script><script src="/assets/js/46.90855a0f.js" defer></script>
  </body>
</html>
